
私はbashを使用してCSVファイル内のフィールドを見つけ、グループ化し、合計するスクリプトを作成しています。各行にはカンマ区切りのフィールドがあり、それぞれ同様の規則に従います。カンマで区切られた各フィールドには、数値、等号(=)、英数字の値が順番に表示されます。 「(数字)=」は1行に表示されない場合があります。その場合、フィールドの位置は異なる場合がありますが、1行に1回のみ表示されます。また、等号の後の値の長さも異なります。
私の目標の例は最高です。 CSVファイル:
35=D,11=ABCD1,1=ABC,55=XYZ,38=100,40=P,18=M,54=1,59=0,10=111
35=D,11=ABCD2,1=ABC,55=XYZ,40=P,18=M,38=200,54=1,44=10.00,59=0,10=133
35=D,11=ABCD3,1=ABC,55=XYZ,40=P,18=M B,54=1,38=300,44=10.00,59=0,110=200,10=113
35=D,11=ABCD4,1=ABC,55=XYZ,38=400,40=P,18=M B F,54=1,44=10.00,59=0,110=300,10=144
35=D,11=ABCD5,1=ABC,55=ZYX,38=300,40=2,54=1,44=10.00,59=3,10=132
35=D,11=ABCD6,1=ABC,55=ZYX,38=100,40=1,18=C,54=2,59=3,10=131
「38 =」で始まるすべてのフィールドを識別し、「=」の後のすべての数値を合計して各「55 =」にグループ化するスクリプトが必要です。各行には「38 =」と「55 =」があります。
上記のファイルを使用した出力は次のとおりです(ソートはオプション)。
55=XYZ 38=1000
55=ZYX 38=400
答え1
ミラーを使ってhttp://johnkerl.org/miller/doc、これからinput.csv
35=D,11=ABCD1,1=ABC,55=XYZ,38=100,40=P,18=M,54=1,59=0,10=111 35=D,11=ABCD2,1=ABC,55=XYZ,40=P,18=M,38=200,54=1,44=10.00,59=0,10=133 35=D,11=ABCD3,1=ABC,55=XYZ,40=P,18=M B,54=1,38=300,44=10.00,59=0,110=200,10=113 35=D,11=ABCD4,1=ABC,55=XYZ,38=400,40=P,18=M B F,54=1,44=10.00,59=0,110=300,10=144 35=D,11=ABCD5,1=ABC,55=ZYX,38=300,40=2,54=1,44=10.00,59=3,10=132 35=D,11=ABCD6,1=ABC,55=ZYX,38=100,40=1,18=C,54=2,59=3,10=131
そして走っている
mlr --ofs " " unsparsify then stats1 -a sum -f 38 -g 55 then rename 38_sum,38 input.csv
あなたはやる
55=XYZ 38=1000 55=ZYX 38=400
答え2
Steeldriverは私に少し勝ったが、私は見つけた。
perl -F'[=,]' -lane '
%row = @F;
$sum{$row{55}} += $row{38};
}{
print "$_ = $sum{$_}" for keys %sum
' file.csv
XYZ = 1000
ZYX = 400
答え3
ここに解決策がありますawk
。
awk -F, '{for(a=1;a++<=NF;){
if($a~/^55=/){l=$a}
if($a~/^38=/){b[l]+=substr($a,4)}
}}END{for(x in b){print x,"38="b[x]}}' inp
for(a=1;a++<=NF;){
- カンマで区切られた各フィールドを繰り返します。if($a~/^55=/){l=$a}
- 次に始まるフィールドが見つかったら、55=
それを変数に保存します。l
if($a~/^38=/){b[l]+=substr($a,4)}
- 次から始まるフィールドが見つかったら、変数をキーとして使用して38=
次の値を取得し、=
配列に蓄積します。b
l
}}END{for(x in b){print x,"38="b[x]}}
- 配列の内容のみを印刷
答え4
どうですか?
awk -F, '
{for (i=1; i<=NF; i++) {split ($i, T, "=")
if (T[1] == 55) IX = T[2]
if (T[1] == 38) NM = T[2]
}
SUM[IX] += NM
}
END {for (s in SUM) print "55=" s, "38=" SUM[s]
}
' file
55=ZYX 38=400
55=XYZ 38=1000
すべてのフィールドを繰り返して関連フィールドを見つけ、配列T
に分割し、55
見つかった場合はインデックスを抽出し、見つかった38
場合は合計を抽出します。ループが終了すると、合計が実行されます。END
セクションには、すべての要約値とそのインデックスが表示されます。