大容量ファイルで複数行式で sed を使用する場合のメモリ不足

大容量ファイルで複数行式で sed を使用する場合のメモリ不足

現在、閉じ括弧が前にないすべての改行文字を削除しようとしているので、次の式を考えました。

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()

おすすめ記事