sedで何度も再利用するために複雑な正規表現を保存する方法は?

sedで何度も再利用するために複雑な正規表現を保存する方法は?

使用中は、sedファイル内で2回一致する必要があるかなり複雑な正規表現を作成することがよくあります。この正規表現を保存して2回だけ参照する方法はありますか?

たぶんこんなことがあったのでしょうか?

sed ' complicated_regex=/^(([a-f0-9]{32})+([a-zA-Z0-9=]{{$i}})?)+$/
s/complicated_regex:complicated_regex/simple-output/
' my_file

更新:答えはbash変数を使用する解決策を提案します。これはうまくいきません。与えられたtest.txt

#test.txt
foo bar
bar foo

そしてスクリプト

#!/bin/bash

VALUE='foo \([a-z]\+\)'

sed 's/"${VALUE}"/foo happy \1/' test.txt

これにより出力が生成されます。

foo happy bar
bar foo

しかし、エラーが発生しました。

sed: -e expression #1, char 24: invalid reference \1 on `s' command's RHS

答え1

シェル変数を使用できます。

complicated_regex='(([a-f0-9]{32})+([a-zA-Z0-9=]{{$i}})?)+'
sed s/^"$complicated_regex":"$complicated_regex"\$/'simple-output'/ my_file

どういう意味なのかよく分からないが、一重$i引用符の外に入れなければならないようです。

complicated_regex='(([a-f0-9]{32})+([a-zA-Z0-9=]{{'"$i"'}})?)+'

答え2

スクリプトの残りの部分でバックスラッシュエスケープを変更する方法を心配せずにシェル変数の値を入力するsed最も簡単な方法sedは、すべてを一重引用符で囲むことです。とは別に変数を二重引用符で囲みます。

以下のすべてのコード例は、以下を想定しています。VALUE='foo \([a-z]\+\)'

次のような壊れた変数がVALUE拡張されていないため、コードは失敗します。

sed 's/"${VALUE}"/foo happy \1/' test.txt

次のような壊れたバックスラッシュがシェルに表示される前にシェルで食べられるため、コードは失敗します\1(一重引用符ではなく二重引用符で囲まれているため)sed

sed "s/${VALUE}/foo happy \1/" test.txt

次のコードは期待どおりに機能します。

sed 's/'"${VALUE}"'/foo happy \1/' test.txt

次のコードも機能します。

sed "s/${VALUE}/foo happy \\1/" test.txt

次も同様です。

sed s/"${VALUE}"/foo\ happy\ \\1/ test.txt

しかし、なぜ複雑になるのですか?スクリプトの周りの一重引用符は、sed特にコードを読むビシェルスクリプトの専門家にとって、すべてをより明確にします。私の好きな方法は、変数を拡張するために一重引用符から二重引用符に移動し、一重引用符に直接戻ることです。

sed 's/'"${VALUE}"'/foo happy \1/' test.txt

関連情報