sed を使用して「\」を含む文字列を置換するにはどうすればよいですか?

sed を使用して「\」を含む文字列を置換するにはどうすればよいですか?

というファイルがありますマイファイル.txt以下の内容です:

ユーザー名=myusername
暗号化パスワード=9k3S+sS3g\=\=

ユーザー名とパスワードを変更する必要があるたびに、シェル スクリプトを実行します。シェル スクリプトでは、保存したユーザー名とパスワードを次の 2 つの変数に格納します。

oldusername="ユーザー名"
oldpassword="9k3S+sS3g\=\="

newusername="新しいユーザー名"

新しいパスワード="U8djlk+h\=="

sed -i "s/$oldusername/$newusername/g" MyFile.txt

sed -i "s/$oldpassword/$newpassword/g" MyFile.txt

最初の sed は正常に動作し、ユーザー名を置き換えますが、2 番目の sed コマンドは動作せず、ファイル内のパスワードは変更されません。これは、変数に「\」文字が存在するためだと思います。

誰かこの件について私を助けて、どうすればよいか教えてくれませんか?

ありがとう..

答え1

愚かな回避策、すべてのバックスラッシュをエスケープします:

oldpassword="$(printf "$oldpassword" | sed 's/\\/\\\\/g')"
sed -i "s/$oldpassword/$newpassword/g" MyFile.txt

答え2

$ cat MyFile.txt 
Username=myusername
EncryptedPassword=9k3S+sS3g\=\=
$ oldusername="myusername"
$ oldpassword="9k3S+sS3g\=\="
$ newusername="mynewusername"
$ newpassword="U8djlk+h\=="

$ perl -pe "s/\Q$oldusername/q($newusername)/e ; s/\Q$oldpassword/q($newpassword)/e" MyFile.txt
Username=mynewusername
EncryptedPassword=U8djlk+h\==

からパーラードキュメントおよび\Qq()

EXPR の値を返します。ASCII の非単語文字はすべてバックスラッシュで表されます。(つまり、/[A-Za-z_0-9]/ に一致しないすべての ASCII 文字は、ロケール設定に関係なく、返される文字列ではバックスラッシュで始まります。) これは、二重引用符で囲まれた文字列で \Q エスケープを実装する内部関数です。

結果が問題なければ、perl -i -peインプレース編集に使用します。sed

答え3

$oldpasswordの内容をエコーし​​ましたか?$oldpasswordからバックスラッシュが抜けています。

$ oldpassword=9k3S+sS3g\=\=
$ echo $oldpassword
9k3S+sS3g==

そのため、試合は失敗します。

バックスラッシュ文字をそこに入れたい場合は、oldpasswordに割り当てる値を一重引用符で囲んで、シェルがそれらをエスケープシーケンスとして解釈しないようにします。つまり、値をリテラル文字列にします。

$ oldpassword='9k3S+sS3g\=\=

関連情報