非常に大きなファイルの文字列を置き換える

非常に大きなファイルの文字列を置き換える

区切り文字のない次の形式の長い一連のURLがあります。

http://example.comhttp://example.nethttp://example.orghttp://etc...

各URLをラップしたいです。私はsedを使って "http://"のすべてのインスタンスを "\nhttp://"に置き換えることによってこれをやろうとしています。

sed 's_http://_\nhttp://_g' urls.txt

ただし、分割エラー(メモリ違反)が発生します。ファイルの絶対サイズ(100 GB以上)のため、sedがいくつかの制限を超えたと推測できます。

処理のためにファイルを複数の小さなファイルに分割できますが、「http://」のすべてのインスタンスはそのまま残す必要があります。

もっと良い方法がありますか?

答え1

これにより、awk一度に大量のテキストを読み取ることを回避できます。

awk -vRS='http://' -vORS='\nhttp://' 1 urls.txt > urlsperline.txt

成功するかどうかは、使用されている実装によって異なりますawk。たとえば、うまくgawk動作しますが、mawk競合が発生します。

答え2

これにより操作が実行されます。

perl -pe 'BEGIN { $/ = "//" } s!(?=http://\z)!\n!' urls.txt

設定として$///、改行で終わるように行定義を変更しました。これにより、Perlは一度に1つのURLを読み取ります。 URLに//スキームの後を除いては含まれない可能性がありますが、含めても構いません。正規表現は偽の改行を追加するのを防ぎます。

最初のURLの前に空白行を追加したくない場合は、次のようにします。

perl -pe 'BEGIN { $/ = "//"; print scalar <> } s!(?=http://\z)!\n!' urls.txt

ベンチマークを試してより高速であることを確認できますs!http://\z!\nhttp://!。それらは同じです。/g「ライン」ごとに1つの一致がある可能性があるため、交換するときにこのフラグは必要ありません。

答え3

  1. :ファイルを分割するには、aのすべての項目を改行文字に変更します。
  2. 変える
    • http行末で
    • 改行文字の後にhttp:次の行が追加されます。
  3. 一度繰り返すと、偶数行と奇数行の両方が更新されます。

手順は次のとおりです。

tr ':' '\n' | sed -e '/http$/{N;s/http\n/\nhttp:/}' | sed -e '/http$/{N;s/http\n/\nhttp:/}'
  1. で始まらない行があることを確認し、http://行番号を出力してください。 :このURLに存在しない場合にのみ適用されますhttp

    grep -nv '^http://'

関連情報