私は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
内部編集オプションがあることです。sed
sed
sed
また、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