这让我疯了。这是我的困境,我有一个文件,我需要在其中进行匹配。通常我使用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会有更简单的解决方案吗?如果是这样,有人知道从哪里开始吗?
答案 0 :(得分:3)
在参数周围使用单引号以防止对$
,\
等进行特殊处理。如果需要在其中包含单引号,则通用解决方案是使用'\''
。但是,在这种特殊情况下,我们可以避免尝试使用正则表达式中的等效'
来包含\x27
。
perl -nle'
print "$1 => $2"
while /^(?!#)(loop_.+rev).+?[\x27\"|](.+?)[\x27\"|]$/g;
' non-hadoop.env
[为了便于阅读,我添加了一些换行符。如果你愿意,你可以把它们留在里面,但你不需要。]
请注意,您的正则表达式模式存在一些问题。
(?!\#)(loop_.+rev)
与(loop_.+rev)
相同,因为l
不是#
,所以(?!\#)
没有按照您的想法做任何事情
[\'|\"]
匹配'
,"
和|
,但我认为您的意思是匹配'
和"
。如果是,您希望使用[\'\"]
,可以简化为['"]
。
请勿在{{1}},?
等之后使用非贪婪修饰符+
。它用于优化,而不是用于排除字符。事实上,你的模式中的第二个*
绝对没有效果,所以它没有做你认为它正在做的事情。
固定?
?
答案 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