リストをソートし、最初の列が一度だけ表示されるすべての行を印刷する方法を探しています。つまり、最初の列でのみ一致します。たとえば、最初の列がパスで、2番目の列に「type」を含むファイルがあります。
/path/foo/1 footsy
/path/foo/1 barsy
/path/foo/X barsy
/path/bar/2 footsy
/path/bar/2 barsy
/path/foo/Y footsy
(実際のファイルのソートは -k1,1 です)
それでは、次のような状況を抽出したいと思います。
/path/foo/X barsy
/path/foo/Y footsy
以前の行を保存し、前の行の最初のフィールドを現在の行の対応するフィールドと比較する必要があるawkを使用する方法を考えています。しかし、まだ何をすべきかわかりません。 :(他の質問で見つけた解決策を適用しようとしましたが、実際には望みどおりに機能しませんでした。
awk '{
prev=$0; path=$1; type=$2
getline
if ($1 != $path) {
print prev
}
}'
ベストアンサー1
これらの回答には入力ソートは必要ありません。
数と最後の行を配列に保存します。大容量ファイルには多くのメモリが必要で、GNU awkが必要です。
gawk '
{count[$1]++; line[$1]=$0}
END {
PROCINFO["sorted_in"]="@val_str_asc"
for (key in line) if (count[key] == 1) print line[key]
}
' file
ファイルを2回スキャンし、最初に数を取得し、次に1に行を印刷します。
awk 'NR == FNR {count[$1]++; next} count[$1]==1' file file
ソートされた入力を活用するには、最速で最小限のメモリが必要です。
awk '
prev_key && prev_key != $1 {if (count==1) print prev_line; count=0}
{prev_key=$1; prev_line=$0; count++}
END {if (count==1) print prev_line}
' file