したがって、次の形式の入力ファイルがあります。
Hello\tWorld
それから私は利用可能です
awk -F"\t" '!seen[tolower($1)]++'
最初の列に基づいて重複行を削除します。しかし、そのステートメントで条件をどのように設定しますか?つまり、文字列が5回以上使用されている場合は、重複した行のみを削除しますか、それともすべての行を削除しますか?
入力例:
Hello World
Hello World
Hello World
Hello World
Hello World
New Example
Hello World
したがって、上記の例では、column1は5回以上存在するため、予想される出力は次のようになります。
Hello World
New Example
または、特定の行を完全に削除するには
New Example
答え1
式は、配列項目が最初に存在するかどうかをテストするブール値です。効果がある!条件を反転するには。しかし、ずっと計算されている。
ただテストに慣れてください。バージョン6以降の印刷を拒否します。
awk -F"\t" '++seen[tolower($1)] <= 5'
答え2
どちらの例も入力ファイルを2回読み込みます。最初のステップでは最初の列の数を計算し、2番目のステップでは現在の行を印刷して数と比較します。
最初の列が5回以上表示される場合は、最初の発生位置を印刷します。
awk -F'\t' ' FNR==NR{ seen[tolower($1)]++; next } seen[tolower($1)] seen[tolower($1)]>5{ delete seen[tolower($1)] } ' file file
現在の行は、最初の列が配列()にある場合にのみ印刷されます
seen[tolower($1)]
。 5回以上表示されると、配列から削除されます。最初の列が5回以上表示されたら、その行を削除します。
awk -F'\t' ' FNR==NR{ seen[tolower($1)]++; next } seen[tolower($1)]<=5 ' file file
列数が5つ以下の場合にのみ、現在の行を印刷します。
答え3
ファイル全体を配列に保存すると、ファイルを2回読み取ることなくすべての操作を実行できます。つまり、パイプラインで動作します。ファイルを2回読み取るよりも複雑さが高いかどうかは比較しませんでしたが、毎秒約275,000行を処理しています。私は定期的に最大400MBのawk配列を使用するので、データサイズは問題になりません。
入力ファイルのサイズとキー数を表示します。
Paul---) wc 53.txt
100008 187520 1100108 53.txt
Paul---) cut -f1 53.txt | sort | uniq -c
12500 Can
12500 Care
12500 If
12500 Major
12500 Minor
12500 Not
5 Oak
12500 Sample
1 Spruce
2 Willow
12500 With
これは実行とタイミングを示しています。入力データの伝播、残りの行とのキー分離、元のシーケンスの保存を確認するために、いくつかのデバッグも必要です。 Catはパイプ入力を強制するために使用されます。
Paul---) time cat 53.txt | ./5fold
Ln 5590 Num 5 Key :Oak: Oak Fifth
Ln 8654 Num 2 Key :Willow: Willow Pattern China
Ln 13427 Num 1 Key :Spruce: Spruce Only One
Ln 65309 Num 5 Key :Oak: Oak Fourth
Ln 70988 Num 5 Key :Oak: Oak Third
Ln 83982 Num 5 Key :Oak: Oak Second
Ln 87439 Num 5 Key :Oak: Oak First
Ln 99977 Num 2 Key :Willow: Willow Weep for Me
real 0m0.359s
user 0m0.324s
sys 0m0.048s
テストしたコードです。
#! /bin/bash
AWK='''
BEGIN { FS = "\t"; nMax = 5; }
function List (Local, j) {
for (j = 1; j in X; ++j) {
if (N[K[j]] <= nMax)
printf ("Ln %6d Num %d Key :%s: %s\n", j, N[K[j]], K[j], X[j]);
}
}
{ ++N[$1]; K[NR] = $1; X[NR] = $0; }
END { List( ); }
'''
awk -f <( echo "${AWK}" )