私は最近尋ねた。一つの質問他の特定の文字の後に現れる改行文字を削除する方法について説明します。
Unixテキスト処理ツールは非常に強力ですが、ほとんどすべてのテキスト行を処理するため、入力が利用可能なメモリに収まるほとんどの場合は問題ありません。
しかし、改行文字を含まない大容量ファイルで一連のテキストを置き換えるにはどうすればよいですか?
たとえば、入力を1行ずつ読み取らず<foobar>
に次に置き換えますか?\n<foobar>
(1行だけで長さが2.5Gだからです。)
ベストアンサー1
この問題に直面したときに最初に考えたのは、レコード区切り文字を変更することです。ほとんどのツールでは、これは\n
デフォルトで設定されていますが、変更できます。たとえば、
真珠
perl -0x3E -pe 's/<foobar>/\n$&/' file
説明する
-0
: 入力レコード区切り文字を指定した文字に設定します。16進値。この場合は、>
16進値に設定しました3E
。一般的な形式はです-0xHEX_VALUE
。これは行を管理可能な塊に分割するトリックだけです。-pe
:与えられたスクリプトを適用した後、各入力行を印刷します-e
。s/<foobar>/\n$&/
:簡単な交換。$&
この場合、一致するコンテンツはです<foobar>
。
アッ
awk '{gsub(/foobar>/,"\n<foobar>");printf "%s",$0};' RS="<" file
説明する
RS="<"
:入力レコード区切り記号をに設定します>
。gsub(/foobar>/,"\n<foobar>")
foobar>
:のすべてのケースをに置き換えます\n<foobar>
。RS
に設定されているため、入力ファイルから<
すべてが削除されるため(これはうまくいきます)、一致(なし)してに置き換える必要があります。<
awk
foobar>
<
\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
awk
perl
使用されるメモリ量は無視できます。