이것은 내 CSV 파일입니다.
Number;Reference;EANNumber;Manufacturer;Price_B2B;Price_B2B_Dis;Price_B2B_DisPer;Price_B2B_DisAmount;Price_B2C_exVAT;Price_B2C_inVAT
2330113;BP3141;1,31304E+11;APC;13;13;0;0;0;0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1402141;A51U;8,84333E+11;HP;2;2;0;0;0;0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1450121;LC125XLC;4,34444E+12;Brother;11,4;11,4;0;0;0;0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5431414;YEG-00431;343434315;Msoft;11,1;11,1;0;0;31,45;41,31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5533314;QQC-08323;8,85341E+11;Microsoft;522,23;522,23;0;0;0;0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3140025;30MB0SY0-M0EAY0;1,4123E+12;Asus;11,33;11,33;0;0;0;0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1452531;R18-05435;3,33334E+12;Microsoft;24;24;0;0;1,8;1,33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4480158;M28-00002;;Meyss;54,22;54,22;0;0;11,13;31,13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2310152;AC2T0E;;HP;52;52;0;0;0;0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Bash 스크립트를 통해 다음 수식을 실행하고 싶습니다.
=(I2=0;E2*1,2;I2)일 때
가격은 x열에 표시되어야 합니다.
awk나 gawk로 이 작업을 수행할 수 있나요? 노력했지만 더 이상 갈 수 없습니다.
CSV 파일을 읽고 CSV 파일에서 계산을 실행하고 싶습니다.
답변1
해당 값이 0이 아닌 경우 필드 x
값으로 호출되는 새 필드를 원한다고 가정합니다. 이 경우 필드 값의 1.2배를 Price_B2C_exVAT
원합니다 .Price_B2B
다음 코드는 헤더가 있는 "불규칙한" CSV 파일로 입력을 읽고(레코드에 다양한 필드 수가 있기 때문에 "불규칙한") remove-empty-columns
하위 명령을 사용하여 먼저 빈 열을 제거합니다. 그런 다음 x
주어진 수식을 사용하여 각 레코드에 새 필드를 만듭니다.
새 필드의 값을 계산할 수 있습니다.밀러( mlr
) 이와 같이:
mlr --csv --fs ';' --ragged \
remove-empty-columns then \
put '$x = $Price_B2C_exVAT; $x == 0 { $x = 1.2*$Price_B2B }' file.csv
이는 부동 소수점 값이 .
소수점으로 대신 사용되는 경우 잘 작동합니다. ,
대신 Price_B2B
쉼표를 점으로 대체하여 문자열의 값을 부동소수점으로 변환합니다.
mlr --csv --fs ';' --ragged \
remove-empty-columns then \
put '$x = $Price_B2C_exVAT; $x == 0 { $x = 1.2*float(ssub(string($Price_B2B),",",".")) }' file.csv
점 대신 쉼표를 사용하여 부동 소수점 값을 문자열로 변환하려면 x
이전 작업과 반대로 수행합니다 Price_B2B
.
mlr --csv --fs ';' --ragged \
remove-empty-columns then \
put '
$x = $Price_B2C_exVAT;
$x == 0 {
$x = 1.2*float(ssub(string($Price_B2B), ",", "."));
$x = ssub(string($x), ".", ",");
}' file.csv
또는 put -S
Miller가 필드의 데이터 유형을 추론하지 못하도록 하고 이를 문자열로 남겨둡니다(이렇게 하면 Price_B2B
0인 경우 명시적으로 문자열로 변환할 필요가 없습니다).
mlr --csv --fs ';' --ragged \
remove-empty-columns then \
put -S '
$x = $Price_B2C_exVAT;
$x == "0" {
$x = 1.2*float(ssub($Price_B2B, ",", "."));
$x = ssub(string($x), ".", ",");
}' file.csv
질문의 예를 사용한 결과( x
필드가 필드 목록의 끝에 추가됨):
Number;Reference;EANNumber;Manufacturer;Price_B2B;Price_B2B_Dis;Price_B2B_DisPer;Price_B2B_DisAmount;Price_B2C_exVAT;Price_B2C_inVAT;x
2330113;BP3141;1,31304E+11;APC;13;13;0;0;0;0;15,600000
1402141;A51U;8,84333E+11;HP;2;2;0;0;0;0;2,400000
1450121;LC125XLC;4,34444E+12;Brother;11,4;11,4;0;0;0;0;13,680000
5431414;YEG-00431;343434315;Msoft;11,1;11,1;0;0;31,45;41,31;31,45
5533314;QQC-08323;8,85341E+11;Microsoft;522,23;522,23;0;0;0;0;626,676000
3140025;30MB0SY0-M0EAY0;1,4123E+12;Asus;11,33;11,33;0;0;0;0;13,596000
1452531;R18-05435;3,33334E+12;Microsoft;24;24;0;0;1,8;1,33;1,8
4480158;M28-00002;;Meyss;54,22;54,22;0;0;11,13;31,13;11,13
2310152;AC2T0E;;HP;52;52;0;0;0;0;62,400000
답변2
간단한 CSV의 경우 10진수 기준 문자로 사용되는 로케일 awk
에서는 다음을 사용할 수 있습니다 .,
POSIXLY_CORRECT=1 awk -F ';' -v OFS=';' '
{print $0, NR == 1 ? "x" : $9 ? $9 : $5 * 1.2}' < file.csv
추가 필드가 추가됩니다:
- 첫 번째 줄(
NR == 1
) 에는x
- 다른 라인에서는:
$9
(9번째 필드 )가 0이 아닌 경우 ,$9
- 그렇지 않으면 5번째 필드 에 1.2가 곱해집니다.
부동 소수점의 형식을 변경하려면 숫자 변환(두 번째 변수 앞에 0+를 추가하는 등 ) 또는 정수에도 영향을 미치기 때문에 더 나은 방법으로 CONVFMT
변수를 설정합니다(정수에는 영향을 주지 않음) .-v CONVFMT=%.2f
$9
POSIXLY_CORRECT=1 awk -F ';' -v OFS=';' '
{print $0, NR == 1 ? "x" : sprintf("%.2f", $9 ? $9 : $5 * 1.2)}' < file.csv
POSIXLY_CORRECT=1
GNU 의 경우 , awk
GNU가 없으면 GNU는 로케일의 10진수 기준을 존중하지 않습니다.