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 个或多个d
s。在 BRE 中,当位于模式开头或跟随^
或\(
regexp 运算符时,它仅匹配文字*
(它也按字面意思在[...]
括号表达式内获取)。
因此,grep '*README.md*'
匹配包含文字、*
后跟README
任何单个字符(.
正则表达式运算符)、后跟m
任意数量的d
s 的行。自从任何数字包括 0,它在功能上等同于grep '*README.m'
(这对匹配哪些行没有影响,只对行内可能匹配的内容(例如,用--color
GNU 选项显示grep
))。
例如,它将匹配这两行:
*README mike
^^^^^^^^^
DONT***README-mddd
^^^^^^^^^^^^
(^
s 显示该行中的内容与正则表达式匹配,您可以使用 来查看--color
)
在这里,您似乎将正则表达式与 shell 通配符模式混淆了。可以在正则表达式中*
编写匹配 0 个或多个字符的通配符运算符。.*
但做:
grep '.*README\.md.*'
将再次与以下内容相同:
grep 'README\.md'
grep
寻找匹配项时之内行而不是查找与模式完全匹配的行(您需要的-x
)。
使用 ast-open grep
,它也是内置ksh93
的grep
(默认情况下并不总是内置的,您需要通过放在/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
用于固定字符串搜索(.
上面匹配文字.
而不是任何字符)。