CSV 계산을 위한 Bash 스크립트

CSV 계산을 위한 Bash 스크립트

이것은 내 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 -SMiller가 필드의 데이터 유형을 추론하지 못하도록 하고 이를 문자열로 남겨둡니다(이렇게 하면 Price_B2B0인 경우 명시적으로 문자열로 변환할 필요가 없습니다).

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=1GNU 의 경우 , awkGNU가 없으면 GNU는 로케일의 10진수 기준을 존중하지 않습니다.

관련 정보