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

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

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$

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

答案1

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

*是匹配 0 个或多个前面的正则表达式运算符原子。例如,d*匹配 0 个或多个ds。在 BRE 中,当位于模式开头或跟随^\(regexp 运算符时,它仅匹配文字*(它也按字面意思在[...]括号表达式内获取)。

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

例如,它将匹配这两行:

*README mike
^^^^^^^^^
DONT***README-mddd
      ^^^^^^^^^^^^

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

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

grep '.*README\.md.*'

将再次与以下内容相同:

grep 'README\.md'

grep寻找匹配项时之内行而不是查找与模式完全匹配的行(您需要的-x)。

使用 ast-open grep,它也是内置ksh93grep(默认情况下并不总是内置的,您需要通过放在/opt/ast/bin前面来启用它$PATH),您可以使用-K选项 来grep使用 shell 通配符(扩展的 ksh93 通配符)。因此,通过该grep实现,您可以执行以下操作:

grep -K 'README.md'

或者

grep -xK '*README.md*'

匹配包含README.md.

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

grep -xE '(?K)*README.md*'

那里。

通过任何现代grep实施,您还可以执行以下操作:

grep -F README.md

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

相关内容