次のように入力します。
A 13
A 12
B 17
C 33
D 344
C 24
A 5
C 99
最初の列だけの行を取得したいと思います。
B 17
D 344
1つの解決策でawk
あれば良いですが、他の解決策も許可されています。
答え1
順序を混ぜるのが大丈夫なら
sort <file> | uniq -uw 1
詳細については、リソースを参照してくださいman uniq
。重要な部分は次のとおりです。
-u, --unique
only print unique lines
-w, --check-chars=N
compare no more than N characters in lines
答え2
そしてawk
:
awk 'NR==FNR { a[$1]++ } NR!=FNR && a[$1]==1' file file
(ファイル名は2回渡されます。)
編集する:ファイルがソースの場合は、stdin
一時コピーが必要です。このような:
tmp="$( mktemp -t "${0##*/}"_"$$"_.XXXXXXXX )" && \
trap 'rm -f "$tmp"' 0 HUP INT QUIT TERM || exit 1
... | tee "$tmp" | awk '...' - "$tmp"
答え3
やる意思があればアッ
awk '
$1 in ARR{
ARR[$1] = RS;
next;
}
{
ARR[$1] = $0;
}
END{
for(i in ARR)
if(ARR[i] != RS)
print ARR[i];
}
' file
スクリプトは、最初のフィールドをインデックスとして、行全体を値として使用して、行をARR配列に入れます。配列にすでに同じインデックスがある場合は、値を「\ n」(改行)記号に変更します。ファイルの末尾に、値が«\ n»と等しくない配列要素を印刷します。
awkのRS
変数はnewline
基本的に同じです。
それともこれを行うことができます。sed
sort file |
sed '
:a;
$!N;
s/\(\S\+\s\).*\n\1.*/\1\a/;
ta;
/\a/P;
D;
'
答え4
perl -lane '
exists $h{$F[0]} and undef $h{$F[0]},next;
( $h{$F[0]}, $h[@h] ) = ( $_, $F[0] );
END{ print $h{$_} for grep { defined $h{$_} } @h }
' yourfile
コードが行うことは、最初のフィールドが以前に見つかったことを確認することです。その後、その名前のキーがハッシュに存在するため、undef
とにかく配列を構築する必要がないため、その特定のキーの値を計算し続けます。結局廃棄されます。代わりに、私たちは小さな記憶刻印を通して同じ情報を渡します。
最初のフィールドが最初に表示されたら、%h
ハッシュを現在の行で埋め、同時にそのキーで@h
配列を追加します。キーが見つかった順序を維持するために、この手順を実行します。注文が気に入らない場合は、この手順を完全にキャンセルできます。
最後に、すべての入力がダイジェストされると、最後のEND
ブロックで配列要素を繰り返して、定義された値を@h
ハッシュする要素のみを見つけます。値が複数回表示されることを忘れないで%h
ください。undef