大容量ファイルで改行文字を含む文字列を置き換える

大容量ファイルで改行文字を含む文字列を置き換える

メモリ効率的な方法で文字列を「バイナリ」検索/置換することができる非ラインベースのツールを知っている人はいますか?バラよりこの問題また。

次のような操作を実行したい+2 GBのテキストファイルがあります。

sed -e 's/>\n/>/g'

これは、a以降に発生した改行をすべて削除したいが、>他の場所で行われた改行は削除しないことを意味しますtr -d

このコマンドは(私が始めた同様の質問に対する回答)は次のように失敗しますcouldn't re-allocate memory

sed --unbuffered ':a;N;$!ba;s/>\n/>/g'

それでは、C言語以外に他の方法はありませんか?私はPerlが嫌いですが、この場合は例外を作りたいです:-)

データに文字があるかどうかわからないので、\n可能であれば他の文字に一時的に置き換えることを避けたいと思います。

良いアイデアがありますか?

答え1

これはPerlでは本当に些細なことなので、憎むべきではありません!

perl -i.bak -pe 's/>\n/>/' file

説明する

  • -i:ファイルを所定の場所に編集し、という名前の元のファイルのバックアップを作成しますfile.bak。バックアップが必要ない場合は、使用してくださいperl -i -pe
  • -pe:入力ファイルを1行ずつ読み、与えられたスクリプトを適用して各行を印刷します-e
  • s/>\n/>/:交換してくださいsed

awk1つの方法は次のとおりです。

awk  '{if(/>$/){printf "%s",$0}else{print}}' file2 

答え2

一方perl通行:

$ perl -pe 's/(?<=>)\n//'

説明する

  • s///文字列の置換に使用されます。
  • (?<=>)振り返るモードです。
  • \n改行文字と一致します。

全体のパターンは、>以前のすべての改行を削除することを意味します。

答え3

これはどうですか:

sed ':loop
  />$/ { N
    s/\n//
    b loop
  }' file

-uGNU sedの場合は、質問に従って()オプションを追加してみることもできます。--unbufferedGNU sedはこれを簡単な一行で喜んでいます:

sed ':loop />$/ { N; s/\n//; b loop }' file

答え4

sed最終改行なしで出力をエクスポートする方法を提供しません。使用中のアプローチはN基本的に有効ですが、不完全な行をメモリに保存するため、行が長すぎると失敗する可能性があります(sed実装は通常非常に長い行を処理するようには設計されていません)。

代わりに awk を使用できます。

awk '{if (/<$/) printf "%s", $0; else print}'

別のアプローチは、頻繁に発生する「退屈な」文字を使用してtr改行を変更することです。ここでは、スペースが重要な役割を果たすことができます。データのすべての行または少なくともほとんどの行に表示される傾向がある文字を選択してください。

tr ' \n' '\n ' | sed 's/> />/g' | tr '\n ' ' \n'

関連情報