sed sh 脱出問題

sed sh 脱出問題

目標にとても近づいていますが、今は詰まっています。

phpmyadmin設定ファイルを簡単に編集するために自動化されたスクリプトを作成しようとしています。

cat /usr/share/phpmyadmin/config.sample.inc.php |sed s^//\ \$cfg\\[\'Servers\'^\$cfg\\[\'Servers\'^

//基本的に。で始まるすべての行を削除しようとしています// $cfg['Servers']。上記の行はトリックを行いますが、私がしなければならないすべてのエスケープ作業に満足していません。私はこのsedコマンドの何百ものバリエーションを試しましたが、他のすべての文字をエスケープすることがこれまでに機能する唯一の方法のようです。

sudo sh -cもう一つの障害:最終的には上記のコマンド文字列を昇格シェル(使用)を介して渡したいと思います。たとえば、次のようになります。

sudo sh -c "cat /usr/share/phpmyadmin/config.sample.inc.php |sed s^//\ \$cfg\\[\'Servers\'^\$cfg\\[\'Servers\'^  >/usr/share/phpmyadmin/config.inc.php"

ただし、これを試みるたびに次のエラーが発生します。

sed: -e expression #1, char 27: unterminated `s' command

だから私の質問は次のとおりです。sedあまりにも多くの文字をエスケープする必要がないように表現を単純化できますか?コマンドに違反しないように、表現を昇格シェルに渡すにはどうすればよいですかsed s

私の主な問題は、上昇したシェルに二重引用符で区切られた文字列が渡され、sed文字列に一重引用符が含まれていることです。過去には通常、両方を使用するコマンドがなかったので、一方を別のものに置き換えることができました。

答え1

スクリプトを二重引用符で正しく囲むと、スペースと一重引用符をエスケープする必要はありません。

sed "s^// \$cfg\['Servers'^\$cfg['Servers'^" file

また、代替項目の角かっこをエスケープする必要はありません。正規表現の括弧はエスケープする必要があります。そうでなければ、特殊な正規表現記号として理解されるからです。

エスケープを最小限に抑えるための最善の方法は、sedコマンドをファイルに入れて、二重引用符を必要とせず、$シェル拡張で置き換えるときにドル記号を保護する必要がないようにすることです。

servers.sed:

s^// \$cfg\['Servers'^$cfg['Servers'^

次に、次のように実行します。

sed -f servers.sed file

最後の形式は、上昇したシェルでも使いやすいです。

sudo sh -c 'sed -f servers.sed file > newfile'

答え2

問題を簡素化するのに役立ついくつかの観察事項は次のとおりです。

ファイルを作成catしてレンダリングするsed必要はありませんstdin。ファイル名を取得したり、sedパラメータリストで<演算子を使用したりすることもできます。

コマンドラインで引用符をユーザーの責任で見ないでください。shellコマンドを引用符で囲むと機能します。

コマンドに一重引用符がすでにあるので、sed二重引用符を使用するのは簡単です。

  • $ただし、その後は二重引用符で囲まれた文字をオフにする必要がありますshell
  • 角かっこは[リテラルとして解釈されると予想して引用する必要がありますsed

これでshell問題が解決します。sedそれでは、コマンドを見てみましょう。

ここでは不必要に交換部品を繰り返しています。目的は、前の二重スラッシュを削除することだけですので、コマンド/selectline/s/pat/repl/形式を使用する必要がありますs///

その行はすでに選択されているので、最初の3文字(//とスペース)が何であるかを知ることができます。

このコマンドには微妙なエラーが隠されていますsed。代替コマンド区切り文字として使用することを選択したので、最初の行^文字として使用されなくなりました。

言い換えれば、regexこれは行のどの位置でも二重スラッシュを変更できることを意味します。明らかに、それはあなたの仕様が言うものではありません。だから我々は別の区切り記号を使用します。|

 base=/usr/share/phpmyadmin
 if=$base/config.sample.inc.php
 of=$base/config.inc.php
 < "$if" \
    sed -e "\\|^// \$cfg\\['Servers']|s/...//" \
 > "$of" 

sedコマンドラインで一重引用符を使用して、バックスラッシュの負荷を少し減らすこともできます。

sed -e '\|^// $cfg\['\''Servers'\'']|s/...//' 

今、sudo部分に進みます。sedコマンドをshell文字列としてインタプリタに渡します。代わりに、shell's stdinheredoc演算子を介してコマンドを渡すことができます<<

sudo sh <<\eof
base=/usr/share/phpmyadmin
if=$base/config.sample.inc.php
of=$base/config.inc.php
< "$if" sed -e "\\|^// \$cfg\\['Servers']|s/...//" > "$of"
eof

ファタイ

PSターミナルから離れていて、まだテストしていません。

関連情報