![](/img/trans.png)
[英]Perl one liner regex throwing bash: syntax error near unexpected token `)'
[英]Why do I get “-bash: syntax error near unexpected token `('” when I run my Perl one-liner?
这让我发疯。 这是我的难题,我有一个需要匹配的文件。 通常,我使用Perl,它的工作原理就像是一种魅力,但是在这种情况下,我正在编写Shell脚本,由于某种原因,它会引发错误。
这是我要匹配的内容:
loop_loopStorage_rev='latest.integration'
我需要匹配loop
和latest.integration
。
这是我的正则表达式:
^(?!\#)(loop_.+rev).*[\'|\"](.*)[\'|\"]$
当我在Perl脚本中使用它时, $1
和$2
给我适当的输出。 如果我这样做:
perl -nle "print qq{$1 => $2} while /^(?!#)(loop_.+rev).+?[\'|\"](.+?)[\'|\"]$/g" non-hadoop.env
我收到错误:
-bash: syntax error near unexpected token `('
我相信这与我的正则表达式的开始部分有关。 所以我真正的问题是,使用sed,egrep或awk会有更简单的解决方案吗? 如果是这样,有人知道从哪里开始吗?
在参数周围使用单引号以防止对$
, \\
等进行特殊处理。如果需要在其中包含单引号,则通用解决方案是使用'\\''
。 但是,在这种特殊情况下,我们可以避免在正则表达式模式中使用等效的\\x27
来尝试包含'
。
perl -nle'
print "$1 => $2"
while /^(?!#)(loop_.+rev).+?[\x27\"|](.+?)[\x27\"|]$/g;
' non-hadoop.env
[我添加了一些换行符以提高可读性。 如果需要,您实际上可以将它们留在里面,但是您不必这样做。]
请注意,您的正则表达式模式存在一些问题。
(?!\\#)(loop_.+rev)
与(loop_.+rev)
相同,因为l
不是#
,所以(?!\\#)
并没有做您认为正在做的事情。
[\\'|\\"]
匹配'
, "
和|
,但我认为您只希望它匹配'
和"
。如果是,则要使用[\\'\\"]
,可以将其简化为['"]
。
不要使用非贪婪修饰符( +
, *
等之后的?
)。 它用于优化,而不用于排除字符。 其实第二?
在您的模式中绝对没有任何作用,因此它没有按照您认为的去做。
固定?
perl -nle'
print "$1 => $2"
while /^(loop_.+rev).+[\x27"]([^\x27"]*)[\x27"]$/g;
' non-hadoop.env
双引号使Bash用这些shell变量的值替换变量引用,例如$1
和$2
。 在Perl脚本周围使用单引号可以避免这种情况(或在脚本中引用每个美元符号,反引号等)。
但是,您不能轻易地将单引号转义为单引号。 Perl字符串中常见的解决方法是改用字符代码\\x27
。 如果需要单引号的Perl字符串,请使用广义的单引号运算符q{...}
。
如果您需要插入外壳变量名称,一个常见的技巧是使用“跷跷板”引号。 除去引号后,shell中的字符串'str'"in"'g'
等于'string'
; 您可以类似地使用相邻的单引号和双引号字符串来构建脚本……尽管它确实变得相当难以理解。
perl -nle 'print "Instance -> $1\nRevision -> $2"
while /^(?!#)('"$NAME"'_.+rev).+[\x27"]([^\x27"]*)[\x27"]$/g' non-hadoop.en
(请注意,选项-nle
不是脚本的一部分;脚本是-e
选项的加引号的参数。实际上perl '-nle script ...'
同时使用,但绝对可以理解,令人困惑。)
由于你们所有人的帮助,我最终弄清楚了。 再次感谢。 这是我的最后命令
perl -nle 'print "$1 $2" while /^($ENV{NAME}_.+rev).+\x27(.+)\x27/g;' $ENVFILE
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.