私が見つけることができることから、単一引用符を使用すると、内部のすべてがリテラルと見なされます。私の代わりにそれが欲しい。しかし、一重引用符または二重引用符を含む文字列も見つけたいです。
例えば、
sed -i 's/"http://www.fubar.com"/URL_FUBAR/g'
「http://www.fubar.com」をURL_FUBARに置き換えたい。 sedはどのようにして//または二重引用符を認識するのですか?
助けてくれてありがとう!
編集:s/\"http\:\/\/www\.fubar\.\com\"/URL_FUBAR/g
を使用できますか?
\は実際に単一引用符内の文字をエスケープしますか?
sed
コマンドを使用すると、s
コマンドの区切り文字として/
の代わりに他の文字を使用できます。
sed 's#"http://www\.fubar\.com"#URL_FUBAR#g'
または
sed 's,"http://www\.fubar\.com",URL_FUBAR,g'
二重引用符は問題ではありません。単一引用符を一致させるには、2種類の引用符を切り替えます。単一引用符で囲まれた文字列には、単一引用符が含まれない場合があります(エスケープされたものでさえも)。
sed
がドットを解釈し、任意の1文字と一致する正規表現パターン.
としてではない場合、ドットをエスケープする必要があります。
単一引用符については、文字列let's
をlet us
に置き換えるために使用される以下のコードを参照してください。
コマンド:
echo "hello, let's go"|sed 's/let'"'"'s/let us/g'
結果:
こんにちは、行かせて
単一引用符内の単一引用符をエスケープすることは困難です。これを試して:
sed "s@['\"]http://www.\([^.]\+).com['\"]@URL_\U\1@g"
例:
$ sed "s@['\"]http://www.\([^.]\+\).com['\"]@URL_\U\1@g" <<END
this is "http://www.fubar.com" and 'http://www.example.com' here
END
生産する
this is URL_FUBAR and URL_EXAMPLE here
私の問題は、sed式自体の内部に動的変数があるため、式の外側に""
が必要だということでした。したがって、実際の解決策は、lenジャックマンからのもので、sed正規表現内の"
を[\"]
に置き換えることです。
だから私の完全なbashは:
RELEASE_VERSION="0.6.6"
sed -i -e "s#value=[\"]trunk[\"]#value=\"tags/$RELEASE_VERSION\"#g" myfile.xml
ここは:
#
はsedセパレーターです
[\"]
= "
正規表現で
値= \"tags/$RELEASE_VERSION\"
=置換文字列、重要なのは引用符用の\"
だけである
二重引用符のエスケープは、sedでは絶対に必要です。たとえば、sed式全体で二重引用符を使用している場合(シェル変数を使用するときに行う必要があります)。
以下は、sedでのエスケープについて触れた例ですが、bashでの引用に関する他の問題もいくつか示しています。
# cat inventory
PURCHASED="2014-09-01"
SITE="Atlanta"
LOCATION="Room 154"
繰り返し使用できるsedスクリプトを使用して部屋を変更したい場合、次のように入力を可変化します。
# i="Room 101" (these quotes are there so the variable can contains spaces)
このスクリプトは、行がない場合は行全体を追加するか、(sedを使用して)行にテキストと$ iの値を単に置き換えます。
if grep -q LOCATION inventory; then
## The sed expression is double quoted to allow for variable expansion;
## the literal quotes are both escaped with \
sed -i "/^LOCATION/c\LOCATION=\"$i\"" inventory
## Note the three layers of quotes to get echo to expand the variable
## AND insert the literal quotes
else
echo LOCATION='"'$i'"' >> inventory
fi
追伸コメントを解析可能にするために、上記のスクリプトを複数行に分けて書きましたが、次のようなコマンドラインのワンライナーとして使用します。
i="your location"; if grep -q LOCATION inventory; then sed -i "/^LOCATION/c\LOCATION=\"$i\"" inventory; else echo LOCATION='"'$i'"' >> inventory; fi
余談:変数を正しく解釈するには、BASH変数を含むsed式を二重("
)で囲む必要があります。
also$ BASH変数を二重引用符で囲む場合(推奨される方法)
...次に示すように、変数の二重引用符をエスケープできます。
sed -i "s/foo/bar ""$VARIABLE""/g" <file>
つまり、$ VARIABLEに関連付けられた"
を""
に置き換えます。
(単に、"$VAR"
を\"$VAR\"
としてエスケープすると、"
で囲まれた出力文字列になります。)
例
$ VAR='apples and bananas'
$ echo $VAR
apples and bananas
$ echo "$VAR"
apples and bananas
$ printf 'I like %s!\n' $VAR
I like apples!
I like and!
I like bananas!
$ printf 'I like %s!\n' "$VAR"
I like apples and bananas!
ここで、$ VARはsedにパイピングする前に"
- quoted(sedは'
-または"
- quoted)です:
$ printf 'I like %s!\n' "$VAR" | sed 's/$VAR/cherries/g'
I like apples and bananas!
$ printf 'I like %s!\n' "$VAR" | sed 's/"$VAR"/cherries/g'
I like apples and bananas!
$ printf 'I like %s!\n' "$VAR" | sed 's/$VAR/cherries/g'
I like apples and bananas!
$ printf 'I like %s!\n' "$VAR" | sed 's/""$VAR""/cherries/g'
I like apples and bananas!
$ printf 'I like %s!\n' "$VAR" | sed "s/$VAR/cherries/g"
I like cherries!
$ printf 'I like %s!\n' "$VAR" | sed "s/""$VAR""/cherries/g"
I like cherries!
それと比較してください:
$ printf 'I like %s!\n' $VAR | sed "s/$VAR/cherries/g"
I like apples!
I like and!
I like bananas!
$ printf 'I like %s!\n' $VAR | sed "s/""$VAR""/cherries/g"
I like apples!
I like and!
I like bananas!
... 等々 ...
結論
標準的な慣行としての私の推奨事項は
"
- quote BASH変数("$VAR"
)"
- quote、again、sed式で使用される変数(""$VAR""
)(それ自体は"
-でなければなりません) '
- quotedではなく、引用符で囲まれています)$ VAR='apples and bananas'
$ echo "$VAR"
apples and bananas
$ printf 'I like %s!\n' "$VAR" | sed "s/""$VAR""/cherries/g"
I like cherries!
Prompt% cat t1
This is "Unix"
This is "Unix sed"
Prompt% sed -i 's/\"Unix\"/\"Linux\"/g' t1
Prompt% sed -i 's/\"Unix sed\"/\"Linux SED\"/g' t1
Prompt% cat t1
This is "Linux"
This is "Linux SED"
Prompt%