文字列を置き換えるための非ライン指向ツール?

文字列を置き換えるための非ライン指向ツール?

私は最近尋ねた。一つの質問他の特定の文字の後に現れる改行文字を削除する方法について説明します。

Unixテキスト処理ツールは非常に強力ですが、ほとんどすべてのテキスト行を処理するため、入力が利用可能なメモリに収まるほとんどの場合は問題ありません。

しかし、改行文字を含まない大容量ファイルで一連のテキストを置き換えるにはどうすればよいですか?

たとえば、入力を1行ずつ読み取らず<foobar>に次に置き換えますか?\n<foobar>(1行だけで長さが2.5Gだからです。)

ベストアンサー1

この問題に直面したときに最初に考えたのは、レコード区切り文字を変更することです。ほとんどのツールでは、これは\nデフォルトで設定されていますが、変更できます。たとえば、

  1. 真珠

    perl -0x3E -pe 's/<foobar>/\n$&/' file
    

    説明する

    • -0: 入力レコード区切り文字を指定した文字に設定します。16進値。この場合は、>16進値に設定しました3E。一般的な形式はです-0xHEX_VALUE。これは行を管理可能な塊に分割するトリックだけです。
    • -pe:与えられたスクリプトを適用した後、各入力行を印刷します-e
    • s/<foobar>/\n$&/:簡単な交換。$&この場合、一致するコンテンツはです<foobar>
  2. アッ

    awk '{gsub(/foobar>/,"\n<foobar>");printf "%s",$0};' RS="<" file
    

    説明する

    • RS="<":入力レコード区切り記号をに設定します>
    • gsub(/foobar>/,"\n<foobar>")foobar>:のすべてのケースをに置き換えます\n<foobar>RSに設定されているため、入力ファイルから<すべてが削除されるため(これはうまくいきます)、一致(なし)してに置き換える必要があります。<awkfoobar><\n<foobar>
    • printf "%s",$0:交換後、現在の「行」を印刷します。$0は現在のレコードawkなので、前のレコードはすべて保持されます<

以下を使用して生成された2.3GBの単一行ファイルでテストしました。

for i in {1..900000}; do printf "blah blah <foobar>blah blah"; done > file
for i in {1..100}; do cat file >> file1; done
mv file1 file

awkperl使用されるメモリ量は無視できます。

おすすめ記事