次の形式の非常に大きなテキストファイル(数GB)があります。
1 2
3 4
3 5
3 6
3 7
3 8
3 9
ファイルはすでにソートされており、二重行が削除されています。削除したい「21」、「43」の逆順のような繰り返しのペアがあります。非常にリソースが限られた環境、BASH、AWK、perl、または同様の言語でそれを行うためのソリューションはありますか?ファイル全体をロードして値の間をループすることはできません。
2番目の数値が最初の数値よりも小さい行を削除しますか?
perl -i~ -lane'print if $F[0] < $F[1]' file
考えられる解決策:
私はまだディスクスイープの観点からより効率的な解決策を考えていますが、これは基本的な素朴なアプローチです
値ごとに、メモリにロードせずに、ハードドライブ上のファイルに対してバイナリ検索を実行します。重複が表示された場合は削除してください。次に、2つ以上のすべてのインスタンスを削除する最終パスを実行します\n
。
これが機能するかどうか/それが何か良いかどうかは正確にはわかりません...
awk '{ if ($2 > $1) print; else print $2, $1 }' hugetext | sort -nu -O hugetext
重複を考慮1 2
して削除2 1
し、同じにしたいですか?
< file.in \
| perl -lane'print "@F[ $F[0] < $F[1] ? (0,1,0,1) : (1,0,0,1) ]"' \
| sort -n \
| perl -lane'$t="@F[0,1]"; print "@F[2,3]" if $t ne $p; $p=$t;' \
> file.out
これは、任意の大きなファイルを処理できます。
perl -lane '
END{
print for sort {$a<=>$b} keys %h;
}
$key = $F[0] < $F[1] ? "$F[0] $F[1]" : "$F[1] $F[0]";
$h{$key} = "";
' file.txt
説明:
$key
1番目と2番目の値をスペースで連結してハッシュキー変数を作成します$hash{$key}
私は何も定義しませんでしたハッシュキーは本質的に一意であるため、重複することはありません。
Unix
新しいファイルを作成するには、リダイレクトを使用する必要があります。
これを1パスで実行する一般的なO(n)アルゴリズムは次のとおりです(ループやソートは必要ありません)。
これには、実行にO(n)時間かかり、ブラックリストのO(n)ストレージが必要です。(ブラックリストと照合して行を削除するためにファイルをr / wとして操作した場合、結果の追加ストレージはありません)