尝试匹配和排除 grep 中的括号时未找到 bash 事件

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仅打印一行的匹配部分

Mik*_*kel 7

单引号和双引号的规则不同。

由于您显示的原因,在 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)


cuo*_*glm 2

你可以用简单的方法来做到这一点awk

$ echo '(foo),(bar,baz(word,right),(end)' | awk -F'),' '{print $2}'
(bar,baz(word,right
Run Code Online (Sandbox Code Playgroud)