使用中は、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