というファイルがありますマイファイル.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\==
からパーラードキュメントおよび\Q
q()
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\=\=