sedでbash文字列変数への参照を使用する

sedでbash文字列変数への参照を使用する

私はLinuxにとって比較的初心者です。a.txt次のテキストを含むテキストファイルがあるとします。

A
B
C

2行目(含まれている)のテキストを変更するには、B次のsedコマンドを使用できます。

sed -i '2s/^.*$/X/' a.txt

たとえば、Bに変更します。X

sedしかし、2行目のテキストを次に変更するコマンドを作成したいとしましょう。含むbash 文字列変数。 2行目のテキストを引用fname="myaddress"符が明示的に埋め込まれたものにmyaddress変更したいと思います。bash 文字列変数(他の場所で定義されています)これを試すために、mytest.sh次の内容を含むbashシェルスクリプトを作成しました。

#!/bin/bash

myaddress="/home/"
echo fname=\"$myaddress\"

head a.txt
sed -i '2s/^.*$/fname=\"$myaddress\"/' a.txt
head a.txt

echo fname=\"$myaddress\"印刷してくださいfname="/home/"。これが私のテキストです。考える2号線に位置a.txt。ただし、sed代わりにfname="$myaddress"2行目に印刷してくださいa.txt。おそらく周囲のアポストロフィの中にあるからです。つまり、上記のbashシェルスクリプトの出力は次のようになります。

fname="/home/"
A
B
C

A
fname="$myaddress"
C

私の質問は、sed実際にどのように印刷できるかです。? に保存されmyaddress、 ?$myaddressで参照

答え1

s変数の内容に関係なく置換が機能するようにするには、次のような変数sedのコマンドの右側にある特殊文字をエスケープする必要があります。

  • 区切り文字自体(上記で使用/
  • &一致する文字列に置き換えられました
  • エスケープする必要がある改行
  • \上記のすべての内容を超えて、...を紹介するために使用されます\1\2

良い:

escaped_var=$(printf '%s\n' "$var" | sed 's:[/&\]:\\&:g;s/$/\\/')
escaped_var=${escaped_var%?}

sed "s/regexp/$escaped_var/g"

これは非常に面倒なので、次のことをお勧めしますperl

v=$var perl -pe 's/regexp/$ENV{v}/g'

sed次のようになります2s

v=$var perl -pe 's/regexp/$ENV{v}/g if $. == 2'

もちろん、あなたの場合は、次のように書くことをお勧めします。

v=$myaddress perl -pe '$_ = "fname=\"$ENV{v}\"\n" if $. == 2'

もう1つの利点は、バイナリデータも処理でき、GNUベースのシステムでのみ実行できる-i内部編集オプションがあることです。sedsedsed

また、NUL 文字は環境変数に保存できません。

答え2

シェルは一重引用符内の変数を解釈しません。二重引用符に変更する必要があります。変数にスラッシュがあるため、別の区切り文字を使用する必要があります。

sed -i "2s|^.*\$|fname=\"$myaddress\"|" a.txt

$シェルがそれを解釈しないように、行末をエスケープしたことに注意してください。そうではありませんが、$維持したいsを二重引用符で囲んでエスケープする習慣を身に付ける必要があります。これを行うには、いくつかの引用符ペアを使用することもできます。

sed -i '2s|^.*$|fname="'"$myaddress"'"|' a.txt

答え3

2つの問題があります。まず、Kevinがすでに指摘したように、シェル変数をシェルで拡張するには、その変数を二重引用符で囲む必要があります。次に、代替文字列にが含まれているため、区切り文字として使用することも/できません。特定の文字(たとえば)が代替文字列にはっきりと現れないことがわかっている場合は、その文字を区切り文字として使用して次のようになります。/sed,sed

sed -i '2s,^.*$,fname="'"$myaddress"'",' a.txt

関連情報