4つの列を持つファイルがあります。最後の3つの列を比較し、行を削除せずに発生回数を計算したいと思います。各行の前に数字が表示されます。
私のファイルは次のとおりです。
ID-jacob 4.0 6.0 42.0
ID-elsa 5.0 8.0 45.0
ID-fred 4.0 6.0 42.0
ID-gerard 6.0 8.0 20.0
ID-trudy 5.0 8.0 45.0
ID-tessa 4.0 6.0 42.0
私が望む結果は次のとおりです。
3 ID-jacob 4.0 6.0 42.0
2 ID-elsa 5.0 8.0 45.0
3 ID-fred 4.0 6.0 42.0
1 ID-gerard 6.0 8.0 20.0
2 ID-trudy 5.0 8.0 45.0
3 ID-tessa 4.0 6.0 42.0
sortとuniqを試してみましたが、各重複行の最初の行のみが提供されます。
cat file | sort -k2,4 | uniq -c -f1 > outputfile
答え1
大きなファイルをメモリに保存する際に問題がある可能性があります。ソートが完了したら、行を順番に配置するのは難しい作業を実行した後、一致する行だけを保存するため、これは少し優れています。
# Input must be sorted first, then we only need to keep matching lines in memory
# Once we reach a non-matching line we print the lines in memory, prefixed by count
# with awk, variables are unset to begin with so, we can get away without explicitly initializing
{ # S2, S3, S4 are saved field values
if($2 == S2 && $3 == S3 && $4 == S4) {
# if fields 2,3,4 are same as last, save line in array, increment count
line[count++] = $0;
} else {
# new line with fields 2, 3, 4 different
# print stored lines, prefixed by the count
for(i in line) {
print count, line[i];
}
# reset counter and array
count=0;
delete line;
# save this line in array, increment count
line[count++] = $0;
}
# store field values to compare with next line read
S2 = $2; S3 = $3; S4 = $4;
}
END{ # on EOF we still have saved lines in array, print last lines
for(i in line) {
print count, line[i];
}
}
スクリプトは通常awk
ファイルに保存されます。
次のように使用できます。
sort -k2,4 file | awk -f script
3 ID-fred 4.0 6.0 42.0
3 ID-jacob 4.0 6.0 42.0
3 ID-tessa 4.0 6.0 42.0
2 ID-elsa 5.0 8.0 45.0
2 ID-trudy 5.0 8.0 45.0
1 ID-gerard 6.0 8.0 20.0
答え2
助けることができます:
awk '{ pop[$1] = $2" "$3" "$4; x[$2" "$3" "$4]++; } END { for (name in pop) { if (pop[name] in x) { print x[pop[name]], name, pop[name]; } } }' file
popとxという2つの配列を作成します。 pop には column1 と value=colum2" "column3" "column4 のキーがあり、配列 x には配列 pop と count 重複のキーと値があります。最後のループでは、配列xの配列ポップ値で各名前を解決します。
あなたの注文を保留しません。