複雑な正規表現のsed置換は機能しませんが、エラーは発生しません。

複雑な正規表現のsed置換は機能しませんが、エラーは発生しません。

私はCentOS 7で作業しており、find / sed onelinerを使用して大量のファイルを回復しようとしています。具体的には、連続して2つあります。

  1. [monitor://...]まず、各(作業)の直後に「ignoreOlderThan = 14d」を追加します。
  2. 次に、[monitor://...]2つの「ignoreOlderThan」を持つグループを見つけて、最後の項目を削除します。

次のようなファイルが何百ものあります(これが私が使用している現在のテストファイルです)。

[default]
host = 10.2.2.15

[monitor://apath]
ignoreOlderThan = 14d
index=test
sourcetype=whatever
ignoreOlderThan = 30d

[monitor://truck]
ignoreOlderThan = 14d

[monitor://apath]
ignoreOlderThan = 14d
index=test
sourcetype=whatever
ignoreOlderThan = 30d

私が使用した最初の完全なコマンドは次のとおりです。

find -name inputs.conf -exec sed -ie 's/\(\[monitor:.*\]\)/\1\nignoreOlderThan = 14d/g' {} +

これはうまくいきます。ignoreOlderThan = 14dすぐ後ろに追加されました[monitor://...]

2番目は複雑で動作しません。

find -name inputs.conf -exec sed -ie 's/\(\[monitor[^\]]+\][^\[]?\)\(ignoreOlderThan\s?=\s?[0-9]+\w\)\([^\[]+?ignoreOlderThan\s?=\s?[0-9]+\w\)\([^\[]+\)?/\1\3\4/g' {} +

regex101を使用して、いくつかの可能なシナリオをテストしました。

https://regex101.com/r/okCSfl/6

https://regex101.com/r/okCSfl/7

https://regex101.com/r/okCSfl/8

https://regex101.com/r/okCSfl/9

正規表現は動作するので、問題はsedコマンドのどこかにあり、能力がはるかに低下しているようです。キャプチャグループに必要に応じて角かっこをエスケープし、コマンドを実行しますが、何もしません。私は時々4番目のキャプチャグループがないからかもしれないと思いましたが、各グループに4つのキャプチャグループをすべて含むファイルもテストしました。

私はまた、いくつかのsedがすべてを1行として解釈することを読んだ。これが私のテストケースのいくつかが改行の間に空白がない理由です。


編集:@chorobaはsedが一度に1行ずつ実行されることを指摘し、perlを提案し、例を提供しました。私はそれで遊んで、次のように動作させました。

find -name inputs.conf -exec perl -0777 -pi -e 's/(\[monitor:[^[]+?)^(ignoreOlderThan\s?=\s?[0-9]+\w)([^[]+?^ignoreOlderThan\s?=\s?[0-9]+\w[^[]+)/$1$3/gms' {} +

ここのデモ:

https://regex101.com/r/okCSfl/10

答え1

sed は入力を 1 行ずつ処理します。正規表現は複数行を簡単に一致させることはできません。

一方、Perl は-0777オプションが指定された場合、ファイル全体を読み取ることができます。

perl -0777 -pe 's/^(\[monitor:[^[]+^ignoreOlderThan .*)^ignoreOlderThan = \w+/$1/gms' input > output
  • -0777全体のファイルを食べる
  • -p処理後の印刷入力
  • /g交換を繰り返す
  • /s改行文字のマッチング.(通常はそうではありません)
  • /m^文字列全体だけでなく、各改行の先頭に一致します(似ています$が、ここでは必要ありません)。

関連情報