2つの列と1000万行のファイルがあります。最初の列には重複した値がたくさん含まれていますが、列2には異なる値があります。重複した行を削除してを使用して1つだけを維持したいと思いますawk
。注:ファイルは列1の値に基づいてソートされます。たとえば、
1.123 -4.0
2.234 -3.5
2.234 -3.1
2.234 -2.0
4.432 0.0
5.123 +0.2
8.654 +0.5
8.654 +0.8
8.654 +0.9
.
.
.
.
期待される出力
1.123 -4.0
2.234 -3.5
4.432 0.0
5.123 +0.2
8.654 +0.5
.
.
.
.
答え1
さまざまな方法:
アッ
awk '!a[$1]++' file
これは非常に簡潔な作成方法です。
awk '{if(! a[$1]){print; a[$1]++}}' file
したがって、最初のフィールド(
$1
)が現在のa
配列にない場合は、行を印刷して最初のフィールドをその配列に追加しますa
。次のフィールドを表示すると、そのフィールドは配列内にあるため印刷されません。パール
perl -ane '$k{$F[0]}++ or print' file
または
perl -ane 'print if !$k{$F[0]}++' file
これは基本的に以前と同じです
awk
。これ-n
により、Perl は入力ファイルを 1 行ずつ読み込み、提供されたスクリプトを-e
各行に適用します。-a
空白で各行を自動的に分割し、結果フィールドを@F
配列に保存します。最後に、最初のフィールドを%k
ハッシュに追加し、そのフィールドがまだ存在しない場合はその行を印刷します。同じ内容を次のように書くことができます。perl -e 'while(<>){ @F=split(/\s+/); print unless defined($k{$F[0]}); $k{$F[0]}++; }' file
コアツール
rev file | uniq -f 1 | rev
この方法は、最初に行を裏返し、行が
file
12 345の場合は543 21になるように機能します。次に、uniq -f 1
543の列である最初のフィールドを無視します。その中にフィールドがありますfile
。ここで使用される効果uniq
は、重複行をフィルタリングして行ごとに1つだけ残すことです。最後に、別の逆操作を介して行を元の順序に復元します。GNUソート(例:提案寄稿者: @StéphaneChazelas)
sort -buk1,1
この
-b
フラグは先行スペースを無視し、-u
メソッドは一意のフィールドのみを印刷します。賢明なのは、-k1,1
この-k
フラグがソートするフィールドを設定することです。これは一般的な形式です。つまり、ソート時に-k POS1[,POS2]
POS2を介してフィールドのみを確認します。POS1
つまり、-k1,1
最初のフィールドだけを見てください。データに応じて、次のいずれかのオプションを追加することもできます。-g, --general-numeric-sort compare according to general numerical value -n, --numeric-sort compare according to string numerical value
答え2
最初の列の長さが常に5文字の場合は、単に次のものを使用できますuniq
。
uniq -w 5 file
そうでない場合は、以下を使用してくださいawk
。
awk '$1!=a{print $0; a=$1}' file
大容量ファイルの場合、最初のファイルは確かに高速です。