繁体   English   中英

当我运行Perl单行代码时,为什么在意外的标记`(')附近出现“ -bash:语法错误”?

[英]Why do I get “-bash: syntax error near unexpected token `('” when I run my Perl one-liner?

这让我发疯。 这是我的难题,我有一个需要匹配的文件。 通常,我使用Perl,它的工作原理就像是一种魅力,但是在这种情况下,我正在编写Shell脚本,由于某种原因,它会引发错误。

这是我要匹配的内容:

loop_loopStorage_rev='latest.integration'

我需要匹配looplatest.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

[我添加了一些换行符以提高可读性。 如果需要,您实际上可以将它们留在里面,但是您不必这样做。]


请注意,您的正则表达式模式存在一些问题。

  1. (?!\\#)(loop_.+rev)(loop_.+rev)相同,因为l不是# ,所以(?!\\#)并没有做您认为正在做的事情。

  2. [\\'|\\"]匹配'"| ,但我认为您只希望它匹配'" 。如果是,则要使用[\\'\\"] ,可以将其简化为['"]

  3. 不要使用非贪婪修饰符( +*等之后的? )。 它用于优化,而不用于排除字符。 其实第二? 在您的模式中绝对没有任何作用,因此它没有按照您认为的去做。

固定?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM