パイプ区切り文字に基づいて最後の列を合計する必要があります。

パイプ区切り文字に基づいて最後の列を合計する必要があります。

私の入力にはたくさんの行があります。

11|ABCD|19900101123123445455|555|AAA|50505050|0000009030
11|ABCD|19900101123123445455|555|AAA|50505050|0000000199
13|ABCD|201803010YYY66666666|600|ETC|20180300|0000084099
11|ABCD|19900101123123445455|555|AAA|50505050|0008995001

以下の出力を取得する必要があります

11|ABCD|19900101123123445455|555|AAA|50505050|9004230
13|ABCD|201803010YYY66666666|600|ETC|20180300|84099

私は以下でawkを使用しようとしましたが、配列に関する知識が限られています。

cat test|awk -F"|" '{ a[$1]++;b[$2]++;c[$3]++;d[$4]++;e[$5]++;f[$6]+=$6 }; END { for (i in a); print i, f[i]}'

6列の最後の列を合計し、パイプで区切られた最初の5列をすべて印刷し、最後の6列を6列の合計として印刷する必要があります。

答え1

そして牛に似た一種の栄養 datamash注文する:

$ datamash -t'|' -s -g 1,2,3,4,5,6 sum 7 < infile
11|ABCD|19900101123123445455|555|AAA|50505050|9004230
13|ABCD|201803010YYY66666666|600|ETC|20180300|8409

存在するdatamash v1.2+、列の範囲を指定することもできます。

$ datamash -t'|' -s -g 1-6 sum 7 < infile

または最短AWK代替案と現在地窒素列の場合は、すべての列を1つずつ指定しないでください。

awk -F'|' '{x=$NF;NF--; a[$0]+=x} END{for(i in a) print i, a[i]}' OFS='|' infile

答え2

Awk解決策:

awk 'BEGIN{ FS=OFS="|" }
     { a[$1 FS $2 FS $3 FS $4 FS $5 FS $6] += $7 }
     END{ for (i in a) print i, a[i] }' file

出力:

11|ABCD|19900101123123445455|555|AAA|50505050|9004230
13|ABCD|201803010YYY66666666|600|ETC|20180300|84099

答え3

アイデアは正確ですが、このような要件の場合は、最後の列を除く値でハッシュキーを作成し、そのキーを使用して最後の列の値を合計します。句のすべての行が処理されると、END合計値が印刷されます。

awk '
     BEGIN {FS=OFS="|"} {
         hashKey = ""
         for(i=1;i<=(NF-1); i++) {
             hashKey = ( hashKey ? (hashKey FS $i):$i )
         }
         total[hashKey]+=$NF
     }
     END { for ( j in total ) print j, total[j] }
' file

答え4

そしてパール

perl -lne '
    $sum{$1} += $2 if /(.*)\|(.*)/
 } END {
    print "$_|$sum{$_}" for keys %sum
' file

関連情報