現在、閉じ括弧が前にないすべての改行文字を削除しようとしているので、次の式を考えました。
sed -r -i -e ":a;N;$!ba;s/([^\)])\n/\1/g;d" reallyBigFile.log
小さいファイルでは操作を実行しますが、私が使用しているこの大きなファイル(3GB
)ではしばらく動作し、メモリ不足エラーが発生します。
sed: Couldn't re-allocate memory
この問題に直面せずにこれを行う方法はありますか?使用sed
自体は必須ではなく、単に使用したいと思いました。
答え1
最初の3つのコマンドが犯人です。
:a
N
$!ba
これにより、ファイル全体が一度にメモリに読み込まれます。次のスクリプトは、一度に1つのセグメントのみをメモリに保持できます。
% cat test.sed
#!/usr/bin/sed -nf
# Append this line to the hold space.
# To avoid an extra newline at the start, replace instead of append.
1h
1!H
# If we find a paren at the end...
/)$/{
# Bring the hold space into the pattern space
g
# Remove the newlines
s/\n//g
# Print what we have
p
# Delete the hold space
s/.*//
h
}
% cat test.in
a
b
c()
d()
e
fghi
j()
% ./test.sed test.in
abc()
d()
efghij()
このawkソリューションは各行を印刷するため、一度にメモリに1行だけ残ります。
% awk '/)$/{print;nl=1;next}{printf "%s",$0;nl=0}END{if(!nl)print ""}' test.in
abc()
d()
efghij()
答え2
完璧にするために、Perlソリューションは次のとおりです。perl -p -e '/)$/ || chomp'
対称の場合:スクリプトをループで囲み、1行ずつ読み込み、印刷します。 / script-p
式は行末で一致し、一致しない場合(一致がfalse)、改行を削除し続けます。終わり。-e
)
chomp
答え3
これを使用してください:
sed -i -z -u 's/\n/ /g' reallyBigFile.log
-z, --null-data
NUL 文字で行を区切ります。
-u、--unbufferedは、
入力ファイルから最小限のデータをロードし、出力バッファをより頻繁にフラッシュします。