
特殊文字を含む大容量ファイルがあります。私が使用したい複数行のコードがありますsed
。
これ:
text = "\
------ ------\n\n\
This message was automatically generated by email software\n\
The delivery of your message has not been affected.\n\n\
------ ------\n\n"
次のようにする必要があります。
text = ""
次のコードを試しましたが、運がありません。
sed -i '/ text = "*/ {N; s/ text = .*affected.\./ text = ""/g}' /etc/exim.conf
何も置換せず、エラーメッセージも表示しません。
私はそれで遊んだが、試したことはすべてうまくいきません。
答え1
Perlが構造に来ます:
perl -i~ -0777 -pe 's/text = "[^"]+"/text = ""/g' input-file
-i~
ファイルは「所定の位置」で編集され、バックアップコピーは残されます。-0777
1行ずつ読み込むのではなく、ファイル全体を一度に読みます。
置換はs///
sedと同様に機能します(つまり、text = "
二重引用符を除くすべての項目、二重引用符まで複数回一致)。ただし、この場合はファイル全体に適用されます。
答え2
パターンスペースを確認し、N
一致しない場合は、次の行を引き続ける必要があります。
sed '/text = "/{ # if line matches text = "
:b # label b
$!N # pull in the next line (if not the last one)
/"$/!bb # if pattern space doesn't end with " go to label b
s/".*"/""/ # else remove everything between the quotes
}' infile
gnu sed
次のように書くことができます。
sed '/text = "/{:b;$!N;/"$/!bb;s/".*"/""/}' infile
/text = "/,/"/
しかし、これはあまり効率的ではありません。範囲を選択して最初の行を変更したら、残りを削除することをお勧めします。
sed '/text = "/,/"/{ # in this range
/text = "/!d # delete all lines not matching text = "
s/\\/"/ # replace the backslash with quotes (this is only
}' infile # executed if the previous d wasn't executed)
今回もgnu sed
、次のように1行で書くことができます。
sed '/text = "/,/"/{/text = "/!d;s/\\/"/}' infile
答え3
個人的に私はPerlを使ってこれを行います。"
endの前に何もないと仮定できれば、次のようにすることができ"
ます。
perl -0pe 's/(text\s*=\s*)".*?"/$1""/s' file
-0
ファイル全体を食べてメモリに読み込みます。与えられたスクリプトを「適用した後」各行を印刷するという意味です-p
(ここで「行」はフルファイルになります)-e
。スクリプト自体は単純な代替演算子です。text
ゼロ個以上の空白文字が続く文字列をキャプチャし、=
ゼロ個以上の空白文字(text\s*=\s*
)をキャプチャして保存します$1
。次に、$1
キャプチャされたパターンをパターン()と最短の引用符付き文字列に置き換えます""
。このs
フラグを使用すると、.
改行文字が一致します。