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)のとき

価格は×列に表示する必要があります。

awkまたはgawkでこれを行うことはできますか?試してみましたが、もう行けません。

CSVファイルを読み、CSVファイルから計算を実行したいと思います。

答え1

その値がゼロでない場合は、フィールド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_B2Bゼロの場合は明示的に文字列に変換する必要はありません)。

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が掛けられます。

浮動小数点の形式を変更するには、数値変換(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 進数基準を尊重しません。

関連情報