交換したい(弦全体)
$(TOPDIR)/$(OSSCHEMASDIRNAME)
と
/udir/makesh/$(OSSCHEMASDIRNAME)
で試してみました
perl -pi.bak -e "s/\$\(TOPDIR\)\/\$\(OSSCHEMASDIRNAME\)/\/udir\/makesh\/\$\(OSSCHEMASDIRNAME\)/g " makefile
しかし、私は一致しない括弧エラーを取得しています
ドル記号を「2倍」エスケープする必要があります。このような:
echo "\$(TOPDIR)/\$(OSSCHEMASDIRNAME)" | perl -p -e "s/\\$\(TOPDIR\)\/\\$\(OSSCHEMASDIRNAME\)/\/udir\/makesh\/\\$\(OSSCHEMASDIRNAME\)/g"
/
まず、正規表現に使用する必要はありません。それらは単なる標準です。ほぼ何でも使用できます。したがって、コードは次のようになります(一部を単純化して\
):
perl -pi.bak -e "s|\$\(TOPDIR\)/\$\(OSSCHEMASDIRNAME\)|/udir/makesh/\$\(OSSCHEMASDIRNAME\)|g " makefile
"
の代わりにを使用しているため、実際に問題に対処するため'
に、シェルは意味を理解しようとします。$\
これは、(おそらく)何にも置き換えられません。だからあなたが本当に欲しいのは:
perl -p -i.bak -e 's|\$\(TOPDIR\)/\$\(OSSCHEMASDIRNAME\)|/udir/makesh/\$\(OSSCHEMASDIRNAME\)|g' makefile
エスケープについて疑問がある場合は、quotemeta
またはを使用できます\Q ... \E
。
perl -pe 's#\Q$(TOPDIR)\E(?=/\Q$(OSSCHEMASDIRNAME)\E)#/udir/makesh#;'
置換で末尾部分を繰り返す手間を省くために、先読みアサーションを使用していることに注意してください。
解決策は次のquotemeta
ようになります。
perl -pe 'BEGIN { $dir = quotemeta(q#$(TOPDIR)/$(OSSCHEMASDIRNAME)#); }
s#$dir#/udir/makesh/$(OSSCHEMASDIRNAME)#;'
もちろん、実際のワンライナーを使用する必要はありません。シェルの引用が問題を引き起こしている場合、それらすべての中で最も簡単なオプションは、スクリプトの小さなソースファイルを作成することです。
s#\Q$(TOPDIR)\E(?=/\Q$(OSSCHEMASDIRNAME)\E)#/udir/makesh#;
そして実行する:
perl -p source.pl inputfile