0

変更が必要なbashスクリプトがいくつかありますが、手動で実行したくない...基本的に、それらにはすべて次の行が含まれています

for ((i=${BEGIN} ; i < ${END} ; i++))

これを次のように変更する必要があります

for ((i=${BEGIN}-1 ; i < ${END} ; i++))

i=${BEGIN} は一意で、各ファイルに 1 回しか表示されないため、単純な perl コマンドを使用して検索および置換できると考えました。私が思いついたのは

>  perl -w -i -p -e "s/i=\$\{BEGIN\}/i=\$\{BEGIN\}-1/" Script.sh

次のエラーが発生します

syntax error at -e line 1, near "{BEGIN"
syntax error at -e line 1, near "}continue"
Execution of -e aborted due to compilation errors.

ここでの構文エラーは何ですか?

ありがとう!

ツァドキエル

4

2 に答える 2

7

二重引用符の代わりにアポストロフィを使用します。

perl -w -i -p -e 's/i=\$\{BEGIN\}/i=\$\{BEGIN\}-1/'

このように、バックスラッシュはシェルによって削除されないため、perl はバックスラッシュを認識し、エスケープすべきものをエスケープします。

于 2013-01-11T17:38:13.560 に答える
3

bash シェルは"s/i=\$\{BEGIN\}/i=\$\{BEGIN\}-1/"、Perl に到達する前に引数の補間を実行しています。それがどのように機能するか見てみましょう:

$ echo "s/i=\$\{BEGIN\}/i=\$\{BEGIN\}-1/"
s/i=$\{BEGIN\}/i=$\{BEGIN\}-1/

Perl はシーケンスをハッシュ変数のルックアップの開始として扱うため、置換s/i=$\{BEGIN\}/i=$\{BEGIN\}-1/は Perl では問題になりますが、(エスケープされていない) 右中括弧が見つからないため、コンパイルに失敗します。したがって、Perl に本当に見せたいのは、次のようなものです。$\{%\

s/i=\$\{BEGIN\}/i=\$\{BEGIN\}-1/

元のコマンドラインを変更してこれを実現するには、少なくとも 2 つの方法があります。

  1. ドル記号をエスケープします。

    perl -wpi -e "s/i=\\\$\{BEGIN\}/i=\\\$\{BEGIN\}-1/"

  2. bash で補間されない一重引用符を優先します。

    perl -wpi -e 's/i=\$\{BEGIN\}/i=\$\{BEGIN\}-1/'

于 2013-01-11T17:48:41.853 に答える