2列間の差の計算

2列間の差の計算

filename.csv次の内容を含むCSVファイルがあります。

ファイル名.csv:

"Afghanistan","94.0","81.1"
"Bahamas","42.9","43.2"
"Bolivia (Plurinational State of)","86.7","31.9"
"Brazil","76.7","0.0"

2つの列(列2 - 列3)の違いを計算したいが、間違った結果が表示されます。他の列のすべてのデータが消え、減算コマンドで誤った出力が表示されます。

私が使用したコマンドは次のとおりです。awk '{ print $2 - $3 }' filename.csv

私が得た結果は次のとおりです。

0
0
0
0

期待される出力ファイル:

"Afghanistan","94.0","81.1","12.9"
"Bahamas","42.9","43.2","-0.3"
"Bolivia (Plurinational State of)","86.7","31.9","54.8"
"Brazil","76.7","0.0","76.7"

助けてくれてありがとう。ありがとうございます。

答え1

awkのデフォルトの区切り文字は空白ですが、csvは引用符とカンマを使用するため、awkはデフォルトでcsvファイルを1つの大きな列として扱います。

また、数字を認識するには引用符を削除する必要があります。したがって、-F'","'区切り文字をカンマ区切りの引用符付き文字列に変更できます。これは、引用符付き文字列にコンマだけが含まれていない限り機能します。

awk -F'","'  '{ print $2 - $3 }' filename.csv

シェルを引用する必要があります。

答え2

これは働きます:

$ awk 'BEGIN{FS=OFS="\""}{$7=",\""$4-$6"\""}1' filename.csv

出力:

"Afghanistan","94.0","81.1","12.9"
"Bahamas","42.9","43.2","-0.3"
"Bolivia (Plurinational State of)","86.7","31.9","54.8"
"Brazil","76.7","0.0","76.7"

記述子として、もし数値フィールドは引用されていないので、はるかに簡単ですawk -F, '{$4=$2-$3}1' filename.csv

答え3

使用幸せ(以前のPerl_6)

raku -MText::CSV -e 'my @a = csv(in => "/Path/To/File");  \
      my @b = @a.map(*.[1]) Z- @a.map(*.[2]); \ 
     .put for @a Z @b;'

#OR

raku -MText::CSV -e 'my @a = csv(in => "/Path/To/File");  \
      .put for @a Z (@a.map(*.[1]) Z- @a.map(*.[2]));' 

入力例:

"Afghanistan","94.0","81.1"
"Bahamas","42.9","43.2"
"Bolivia (Plurinational State of)","86.7","31.9"
"Brazil","76.7","0.0"

出力例:

Afghanistan 94.0 81.1 12.9
Bahamas 42.9 43.2 -0.3
Bolivia (Plurinational State of) 86.7 31.9 54.8
Brazil 76.7 0.0 76.7

(小規模プロジェクトの場合)csvを直接解析できると確信していますが、ある時点ではCSVパーサーを使用するのが合理的です(挿入された引用符処理、挿入された改行処理、カンマ/カンマではない列区切り文字の検出/変更、空白の切り捨て)。 、等。)。

bashRakuプログラミング言語のコマンドラインからCSVパーサーを呼び出すのがどれほど簡単かを知ることは驚きます。まずText::CSV(モジュール)コマンドラインフラグを使用してモジュールをロードします。-M-MText::CSV-e

最初の例を説明するために@a配列を宣言し、mycsv入力を受け取ります。列1と列2の差をとる(0インデックス)@b配列を宣言します。myこれらの違いは、Zmakeのためにzipメタ演算子に減算演算子を追加することによって達成されますZ-。最後に、Zzipメタ演算子を使用して列@aごとに圧縮された元のcsvを出力します@b

https://github.com/Tux/CSV/blob/master/doc/Text-CSV.pdf(ダウンロードリンクをクリックしてください)
https://docs.raku.org/言語/operators#index-entry-Z_(zip_metaoperator)
https://raku.org

答え4

使用ミラーmlr)はヘッダーなしのCSVファイルを読み取り、2番目と3番目のフィールドの差を計算して新しい4番目のフィールドを作成し、標準書式指定子に従って結果の浮動小数点値を書式設定し、%gCSV引用符を使用して出力します。

$ mlr --csv -N --quote-all put '$4 = fmtnum($2 - $3, "%g")' file
"Afghanistan","94.0","81.1","12.9"
"Bahamas","42.9","43.2","-0.3"
"Bolivia (Plurinational State of)","86.7","31.9","54.8"
"Brazil","76.7","0.0","76.7"

Millerの後続のバージョンでは、フォーマットが破損しているように見えるので、%g同様の%.6g

関連情報