Phi*_*ayo 6 shell grep bash quoting regular-expression
在很长的一行中,我将总结为:
(foo),(bar,baz(word,right),(end)
Run Code Online (Sandbox Code Playgroud)
我只想打印:
(bar,baz(word,right
Run Code Online (Sandbox Code Playgroud)
为了匹配第二个括号,我排除了第三个后面的单词:
$ grep -oP "\\(.*(?!word).*right"
Run Code Online (Sandbox Code Playgroud)
但是 Bash 解释了感叹号:
-bash: !word: 事件未找到
用单引号保护感叹号失败grep: missing )
$ grep -oP '\\(.*(?!word).*right'
$ grep -oP '\\((?!word)(.*right)'
Run Code Online (Sandbox Code Playgroud)
用反斜杠保护感叹号失败grep: unrecognized character after (? or (?-
任何的想法?
注意:-P
用于 Perl 正则表达式,-o
仅打印一行的匹配部分
单引号和双引号的规则不同。
由于您显示的原因,在 bash 中不能可靠地使用双引号,因为没有合理的方法来逃避感叹号。
$ grep -oP "\\(.*(?!word).*right"
bash: !word: event not found
$ grep -oP "\\(.*(?\!word).*right"
grep: unrecognized character after (? or (?-
Run Code Online (Sandbox Code Playgroud)
第二个是因为bash通过\!
而不是!
grep。显示这个:
$ printf '%s' "\!"
\!
Run Code Online (Sandbox Code Playgroud)
当您尝试使用单引号时,双反斜杠并不表示转义的反斜杠,而是表示两个反斜杠。
$ printf '%s' '\\(.*(?!word).*right'
\\(.*(?!word).*right
Run Code Online (Sandbox Code Playgroud)
在单引号内,一切都是文字,并且没有转义,因此编写您正在尝试的正则表达式的方法是:
$ grep -oP '\(.*(?!word).*right'
Run Code Online (Sandbox Code Playgroud)
你可以用简单的方法来做到这一点awk
:
$ echo '(foo),(bar,baz(word,right),(end)' | awk -F'),' '{print $2}'
(bar,baz(word,right
Run Code Online (Sandbox Code Playgroud)