
区切り文字のない非常に長い一連の 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 に//
スキームの後に except が含まれる可能性は低いですが、含まれていても問題ありません。正規表現により、不要な改行が追加されることはありません。
最初の URL の前に空白行を追加したくない場合は、次のようにします。
perl -pe 'BEGIN { $/ = "//"; print scalar <> } s!(?=http://\z)!\n!' urls.txt
ベンチマークを行って、より高速かどうか確認してみるのもよいでしょうs!http://\z!\nhttp://!
。これらは同等です。/g
置換ではフラグは不要であることに注意してください。これは、「行」ごとに 1 つの一致しか存在しないためです。
答え3
:
ファイルを分割するには、すべての a の出現を改行に変更します。- 交換する
http
行末に- 改行に続いて
http:
次の行を追加します
- 1回繰り返して、偶数行と奇数行を更新します
手順は次のようになります。
tr ':' '\n' | sed -e '/http$/{N;s/http\n/\nhttp:/}' | sed -e '/http$/{N;s/http\n/\nhttp:/}'
で始まっていない行があるかどうかを確認し
http://
、行番号を出力します。これは、: が の後以外の URL のどこかにある場合にのみ発生しますhttp
。grep -nv '^http://'