4

次の形式の非常に大きなテキストファイル(数GB)があります。

1 2
3 4
3 5
3 6
3 7
3 8
3 9

ファイルはすでにソートされており、二重行が削除されています。削除したい「21」、「43」の逆順のような繰り返しのペアがあります。非常にリソースが限られた環境、BASH、AWK、perl、または同様の言語でそれを行うためのソリューションはありますか?ファイル全体をロードして値の間をループすることはできません。

4

7 に答える 7

4

2番目の数値が最初の数値よりも小さい行を削除しますか?

perl -i~ -lane'print if $F[0] < $F[1]' file
于 2012-10-18T21:11:05.663 に答える
3

考えられる解決策:

  • ファイルをスキャンする
  • 2番目の値が最初の値よりも小さいペアの場合、2つの数値を交換します
  • 最初の番号、次に2番目の番号でペアを再度並べ替えます
  • 重複を削除する

私はまだディスクスイープの観点からより効率的な解決策を考えていますが、これは基本的な素朴なアプローチです

于 2012-10-18T21:20:58.403 に答える
2

値ごとに、メモリにロードせずに、ハードドライブ上のファイルに対してバイナリ検索を実行します。重複が表示された場合は削除してください。次に、2つ以上のすべてのインスタンスを削除する最終パスを実行します\n

于 2012-10-18T21:11:44.270 に答える
2

これが機能するかどうか/それが何か良いかどうかは正確にはわかりません...

awk '{ if ($2 > $1) print; else print $2, $1 }' hugetext | sort -nu -O hugetext
于 2012-10-18T22:18:06.493 に答える
1

重複を考慮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

これは、任意の大きなファイルを処理できます。

于 2012-10-18T21:27:05.483 に答える
0
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

説明

  1. 現在の行を番号順に並べ替えます
  2. $key1番目と2番目の値をスペースで連結してハッシュキー変数を作成します
  3. $hash{$key}私は何も定義しませんでした
  4. 最後に、番号順にソートされたすべてのキーを印刷します。

ハッシュキーは本質的に一意であるため、重複することはありません。

Unix新しいファイルを作成するには、リダイレクトを使用する必要があります。

于 2012-10-18T21:21:43.723 に答える
0

これを1パスで実行する一般的なO(n)アルゴリズムは次のとおりです(ループやソートは必要ありません)。

  1. ブラックリストとして空のハッシュセットから始めます(セットはキーだけのマップです)
  2. 一度に1行ずつファイルを読み取ります。
  3. 各行について:
    • このペアがすでにブラックリストに含まれていることを確認してください。
    • もしそうなら、それを無視します。
    • そうでない場合は、結果ファイルに追加します。また、スワップされた値をブラックリストに追加します(たとえば、「3 4」と読み、「4 3」をブラックリストに追加した場合)。

これには、実行にO(n)時間かかり、ブラックリストのO(n)ストレージが必要です。(ブラックリストと照合して行を削除するためにファイルをr / wとして操作した場合、結果の追加ストレージはありません)

于 2012-10-18T21:25:41.757 に答える