2

ケース句を bash スクリプトから削除しようとしています。句はさまざまですが、大文字と小文字の一致文字列の一部として常にバックスラッシュが含まれます。

私はsedを試していましたが、bashスクリプト内でawkまたはperlワンライナーを使用できました。

編集の対象は簡単で、次のようになります。

 $cat t.sh
 case N in 
 a\.b); 
   #[..etc., varies] 
 ;;
 esac

バックスラッシュ、セミコロン、またはその両方をエスケープする変数展開に違反しています。「評価」すると、バックスラッシュのエスケープが取り除かれます。そうしないと、セミコロンが追いつきます。そこで、sed内でサブシェル展開を試みました。私が書いたように、これはインタプリタを汚します。セミコロンをさらにエスケープしても効果がないようです。

X='a\.b' ; Y=';;'   
sed -i '/$(echo ${X} | sed -n 's/\\/\\\\/g')/,/$(echo ${Y} | sed -n s/\;/\\;/g')/d t.sh

この:

perl -i.bak -ne 'print unless /${X}/ .. /{$Y}/' t.sh  # which empties t.sh

eval perl -i.bak -ne \'print unless /${X}/ .. /{$Y}/' t.sh  # which does nothing
4

2 に答える 2

0

Bashprintfには、役立つ引用機能があります。

X='a\.b'; Y=';;'
sed "/$(printf "%q" "$X")/,/$(printf "%q" "$Y")/d" t.sh

printfまたは、変数割り当て機能を追加で使用できます。

printf -v X "%q" 'a\.b'
printf -v Y "%q" ';;'
sed "/$X/,/$Y/d" t.sh

sedコマンド引数を二重引用符で囲んでいることに注意してください。一重引用符は、変数の展開とコマンド置換を防ぎます。ただし、それらが使用されていない場合は、通常、一重引用符を使用するのが最善です。

于 2010-06-10T02:24:33.673 に答える
0
X='a\.b'
Y=';;'
perl -i.bak -ne 'print unless /\Q'$X'/ .. /\Q'$Y'/' t.sh

This is playing games with shell quoting, but it works pretty well. :)

于 2010-06-09T20:44:58.723 に答える