次のファイルがあります。
A 1 abc
A 1 def
A 2 ttt
B 2 ppp
B 2 qqq
最初の2つのキーが同じ場合、最初の行を維持したいと思います。これを行います。
A 1 abc
A 2 ttt
B 2 ppp
私が一つ見つけた前の質問これで問題が解決しました。しかし、私のファイルサイズは1.2GBで、最初の19列に一致します。だからこれを実行すると:
awk '!array[$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19]++' infile > outfile
わかりました:
cmd. line:2: (FILENAME=infile FNR=287807) fatal: dupnode: r->stptr: can't allocate memory (Not enough memory)
明らかに、重複したファイルがどこにあるかわからないため、処理するファイルを分割することはできません。この問題を解決するために、メモリと速度を喜んで交換します。 (ファイルには約160万行があります。)
答え1
ファイルがソートされているようです。
sort -m -u -k 1,2 < file
-m
~のためマージファイルを並べ替える試みは行われませんが、代わりに-u
(例:ユニーク-k 1,2
)最初の2つのフィールド(最初の19フィールド)で構成されたソートキーを指定することと組み合わせて、-k 1,19
最初の2つのフィールドから重複する項目を削除します。
ファイルがソートされていない場合(少なくとも2つのフィールドで)、削除するだけです-m
。しかし、結果は最終的にソートされます。ソートはコストがかかりますが、メモリ側では、大容量ファイルをソートするために一時ファイルが使用されるため(sort
使用可能なディスク容量が必要な場合もあります)、大丈夫です。/tmp
$TMPDIR
答え2
同じ列を結合してインデックスを形成することは有効ですか?上記の例を見てみましょう。私たちはできる -
awk '{ind=""; for(i=1; i<3; i++) {ind=ind" "$i } if (!arr[ind]) arr[ind]=$3 } END{for (i in arr) print i, arr[i]}'
A 1 abc
A 2 ttt
B 2 ppp
もちろん、必要なインデックスを結合するには、上記のループを変更する必要があります。
答え3
将来の場合はこれを行うことができます。そして、配列を使用して大容量ファイルの問題を解決できます。フィールド値が変更されるたびに配列が削除されます。
BEGIN{
xd="";
}
{
id=$1;
if (id != xd)
{
for (x in arr)
{
print x,arr[x];
}
delete arr; #Each time the field one changes its value
xd=id;
}
ind="";
for (i=1; i<3; i++)
{
ind=ind $i;
}
if (!arr[ind])
{
arr[ind]=$3;
}
}
END {
for (x in arr)
{
print x,arr[x];
}
}
出力:
$ awk -f script.awk file.txt
A1 abc
A2 ttt
B2 ppp
答え4
この試み:
awk '_a[$1" "$2]++==0' < filename