在 grep 表达式的开头使用通配符会影响输出

use*_*291 4 grep regular-expression wildcards

grep在运行它五次时观察到以下行为:

me@asus:~/go/src/company/topology-front$ lsof |grep 'READ'
vim        4788                  me    4u      REG                8,2     12288   32247694 /home/me/go/src/company/topology-front/.README.md.swp
me@asus:~/go/src/company/topology-front$ lsof |grep 'README.md*'
vim        4788                  me    4u      REG                8,2     12288   32247694 /home/me/go/src/company/topology-front/.README.md.swp
me@asus:~/go/src/company/topology-front$ lsof |grep 'README.md'
vim        4788                  me    4u      REG                8,2     12288   32247694 /home/me/go/src/company/topology-front/.README.md.swp
me@asus:~/go/src/company/topology-front$ lsof |grep '*README.md*'
me@asus:~/go/src/company/topology-front$ lsof |grep '*README.md'
me@asus:~/go/src/company/topology-front$
Run Code Online (Sandbox Code Playgroud)

我不明白为什么最后两次尝试grep没有返回任何结果。

Sté*_*las 22

grep模式是正则表达式(又名正则表达式、正则表达式、RE)、基本正则表达式 (BRE),除非使用了-E/ -F/ -P/ -K/-X选项之一(只有前两个是标准的)。

*是匹配 0 个或多个前面atom 的正则表达式运算符。例如,d*匹配 0 个或多个ds。在 BRE 中,当在模式的开头或跟在^or 正则\(表达式运算符之后时,它*仅匹配文字(它也可以在方[...]括号表达式中按字面意思使用)。

因此grep '*README.md*'匹配包含文字*后跟README任何单个字符(正则.表达式运算符)后跟m任意数量的ds 的行。由于任何数字都包含 0,因此在功能上等同于grep '*README.m'(这对匹配哪些行没有影响,仅对行内可能匹配的内容产生影响(例如,这将与--colorGNU 选项一起显示grep ))。

例如,它将匹配这两行:

*README mike
^^^^^^^^^
DONT***README-mddd
      ^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)

^s 显示行内的内容与正则表达式匹配,您可以用 看到--color

在这里,您似乎将正则表达式与 shell 通配符模式混淆了。*匹配 0 个或多个字符的通配符可以写.*在正则表达式中。但是做:

grep '.*README\.md.*'
Run Code Online (Sandbox Code Playgroud)

将再次与以下相同:

grep 'README\.md'
Run Code Online (Sandbox Code Playgroud)

As在行grep查找匹配项,而不是查找与模式完全匹配的行(您需要)。-x

随着AST-开放grep,这也是ksh93grep内建(并不总是默认内置,并且需要通过将使其能够/opt/ast/bin提前$PATH),你可以使用-K选项grep使用shell通配符(ksh93的扩展的)。因此,通过该grep实现,您可以执行以下操作:

grep -K 'README.md'
Run Code Online (Sandbox Code Playgroud)

或者

grep -xK '*README.md*'
Run Code Online (Sandbox Code Playgroud)

匹配包含README.md.

使用相同的实现,还可以在扩展 ( -E)、增强( -X) 或类似 perl ( -P) 的正则表达式中使用(?K)运算符启用通配符匹配(以及\(?K\)实际上破坏 POSIX 一致性的基本正则表达式,所以我不会依赖它因为它可以在未来的版本中删除)。所以你可以这样做:

grep -xE '(?K)*README.md*'
Run Code Online (Sandbox Code Playgroud)

那里。

使用任何现代grep实现,您还可以执行以下操作:

grep -F README.md
Run Code Online (Sandbox Code Playgroud)

对于固定字符串搜索(.上面匹配文字.而不是任何字符)。