为什么我得到“-bash:语法错误接近意外令牌”(''当我运行Perl单线程时?

时间:2015-06-10 16:32:41

标签: regex linux perl

这让我疯了。这是我的困境,我有一个文件,我需要在其中进行匹配。通常我使用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会有更简单的解决方案吗?如果是这样,有人知道从哪里开始吗?

3 个答案:

答案 0 :(得分:3)

在参数周围使用单引号以防止对$\等进行特殊处理。如果需要在其中包含单引号,则通用解决方案是使用'\''。但是,在这种特殊情况下,我们可以避免尝试使用正则表达式中的等效'来包含\x27

perl -nle'
   print "$1 => $2"
      while /^(?!#)(loop_.+rev).+?[\x27\"|](.+?)[\x27\"|]$/g;
' non-hadoop.env

[为了便于阅读,我添加了一些换行符。如果你愿意,你可以把它们留在里面,但你不需要。]

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

  1. (?!\#)(loop_.+rev)(loop_.+rev)相同,因为l不是#,所以(?!\#)没有按照您的想法做任何事情

  2. [\'|\"]匹配'"|,但我认为您的意思是匹配'" 。如果是,您希望使用[\'\"],可以简化为['"]

  3. 请勿在{{1​​}},?等之后使用非贪婪修饰符+。它用于优化,而不是用于排除字符。事实上,你的模式中的第二个*绝对没有效果,所以它没有做你认为它正在做的事情。

  4. 固定?

    ?

答案 1 :(得分:0)

双引号会导致Bash将$1$2等变量引用替换为这些shell变量的值。在Perl脚本周围使用单引号来避免这种情况(或在脚本中引用每个美元符号,反引号等)。

但是,你不能轻易地在单引号内单引号; Perl字符串中的常见解决方法是使用字符代码\x27。如果您需要单引号Perl字符串,请使用通用单引号运算符q{...}

如果你需要插入一个shell变量名,一个常见的技巧是使用“see-saw”引用。删除引号后,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 ...'巧合地起作用,但它确实是单一的,令人困惑。)

答案 2 :(得分:0)

由于你们所有人的帮助,我最终搞清楚了。再次感谢。这是我的最后一个命令

:set_answer, :show, :edit, :update or :destroy