2016-08-26 109 views
2

我想用根据用户输入生成的字符串替换目录下所有文件的占位符。此输入可以包含/ : . ~在Perl中使用〜搜索并替换

我选择了Perl来完成此任务。

perl -p -i -e "s/__MY_PLACEHOLDER__/$user_input/g" `find my_dir -type f -print0 | xargs -0` 

现在,~是Perl中的保留字符。我怎样才能在$user_input中逃脱~\~不起作用。

+0

我打算提出[这个问题](http://stackoverflow.com/q/7970702/176646)作为重复,但我只是不喜欢接受的答案。实际上你已经结合了两个常见的(但是很好的)问题:1)如何将一个shell变量传递给Perl?和2)我如何逃避正则表达式中的特殊字符?我无法找到一个能同时解决这两个问题的合适问题,所以也许这可能会成为一个新的典型问题。 – ThisSuitIsBlackNot

+2

你应该总是把Perl的单行用单引号括在\ * nix中。偶然插入一个shell变量太容易了,或者触发一个历史命令(例如''perl -e“s!foo!bar!”''出现错误''bash:!foo!bar!“:event not found '在bash中)。您应该使用Perl的'%ENV'散列或将bash变量作为参数传递给Perl脚本。有几个很好的帖子,我会尽力为你找到它们。 – ThisSuitIsBlackNot

+1

我会急着指出,当'find'找到包含空格的文件时,你的'perl'不会做你期望的操作。 –

回答

9

实际上,~不是特殊的双引号字符串文字,例如s///的替换表达式。然而,其他一些是特别的。在列出的四个字符中,如果使用/作为分隔符,/就是特殊情况。


不要试图从shell生成Perl代码!使用下列之一:

export $user_input 
perl -i -pe's/__MY_PLACEHOLDER__/$ENV{user_input}/g' 

USER_INPUT=$user_input perl -i -pe's/__MY_PLACEHOLDER__/$ENV{USER_INPUT}/g' 

perl -i -pe' 
    BEGIN { $user_input = shift } 
    s/__MY_PLACEHOLDER__/$user_input/g 
' "$user_input" 

顺便说一句,你真的错过了xargs点!

perl ... `find my_dir -type f -print0 | xargs -0` 

是没有什么不同

perl ... `find my_dir -type f` 

你想要什么是

find my_dir -type f -print0 | xargs -0 perl ... 

这将通过文件名来perl未重整。如果需要的话,它甚至会使用不同批次的参数多次呼叫perl,以避免触及命令行长度限制。

+0

相关:[什么时候需要'xargs'?](http://unix.stackexchange.com/q/24954/446) – Zaid