使用 grep 使用括号进行分组,并将其与通配符(例如*
或?
)组合,将打印整个文件,但不会突出显示任何匹配项应该已被发现。
例子test.txt
:
find this
asdffind this
find this asdf
sadffind thisasdf
(find this)
(find this)?
grep -in "find this" test.txt
:
找到这个
阿斯达夫找到这个
找到这个叙利亚
国防军找到这个阿斯达夫
(找到这个)
(找到这个)?
grep -in "\(find this\)" test.txt
:
找到这个
阿斯达夫找到这个
找到这个叙利亚
国防军找到这个阿斯达夫
(找到这个)
(找到这个)?
grep -in "\(find this\)\?" test.txt
:
找到这个
找到这个<--为什么不find this
匹配?
asdffind this <-- 为什么不find this
匹配?
找到这个asdf
Sadffind thisasdf <-- 为什么不find this
匹配?
(找到这个)<--为什么不find this
匹配?
(找到这个)? <-- 为什么没有find this
匹配到?
它只?
发现从行首开始的短语。这个角色也是如此*
。
我正在尝试将?
通配符应用于整个短语。如果没有括号,它只会适用于它所在的最后一个单词,是吗?
grep "find this\?"
只适用?
于this
,这不是我想要的。
编辑:
我认为我的问题是我试图将“短语”视为单个单词,这是行不通的。
答案1
我认为你的问题是你认为你需要转义括号才能禁用分组,而实际上,转义括号才是启用分组的原因。例如,要仅打印那些匹配的行(find this)
,您可以运行:
$ grep -in "(find this)" test.txt
5:(find this)
6:(find this)?
当您转义括号 ( \( \)
) 时,您是在告诉grep
不要将(
和)
视为普通字符,而是将其视为特殊的“组”分隔符。例如,这可以让您执行以下操作:
$ echo "foofoo" | grep -o '\(.oo\)\1'
foofoo
它匹配任何后跟两个 Os ( .oo
) 的字符,但因为它位于转义括号中,所以我们现在可以将匹配的任何字符引用为\1
,让我们foofoo
与匹配\(.oo\).*\1
。
同样适用于?
.除非它遵循正则表达式通配符(如 ).
,否则它只是一个普通字符。因此,要仅匹配该行(find this)?
,您可以执行以下操作:
$ grep -in "(find this)?" test.txt
6:(find this)?
答案2
我不知道你实际上想做什么(你的解释没有意义),所以我只会回答解释你发布的命令的作用。正如评论中所述,您可能在旧版本的 grep 中遇到了错误;尝试更新的版本(例如,在现代 Linux 发行版上或来自 Homebrew)。
Grep 搜索包含与指定模式匹配的行。 grep 的输出是整行,无论匹配该行的哪一部分。 (该选项-o
更改了这一点。)例如,grep a test.txt
打印包含 的所有行a
。整行,不仅仅是a
。
特别是,如果模式可以匹配空字符串,那么 grep 将打印所有行。例如,since\?
是零或一运算符,打印包含或包含空字符串grep 'a\?' test.txt
的所有行。a
由于所有行都包含空字符串,因此会打印所有行。
类似地打印包含或空字符串grep "\(find this\)\?"
的所有行,因此它打印所有行。find this
该运算符\?
应用于组find this
(在 grep 的默认正则表达式语法中,反斜杠括号分隔组)。
突出显示应用于行匹配行为的顶部。当有多种方法来匹配一行时,未指定 grep 将考虑匹配哪一部分,除非文档(从 GNU grep 2.25 开始)声明如果可能,将使用非空匹配。我认为 GNU grep 使用最长的匹配。
请注意,运算符从未应用于“单词”。它们适用于之前的特点或者括号内的组。例如,find this\?
意思是“要么find this
” find thi
——\?
运算符仅适用于最后一个s
。要匹配 或find
,find this
请使用组:find\( this\)\?
。