grep命令中文手册(info grep翻译)(6)

为什么'grep -lv'输出的是包含非匹配行的文件名?
'grep -lv'列出的是包含一行或多行非匹配行的文件名。如果想要列出无匹配内容的文件名,则使用"-L"选项。 (注:例如a.txt中一部分行匹配到了,一部分行没匹配到,而b.txt中完全没有匹配上,则grep -lv将输出a.txt,而不是b.txt。因此可推测"-v"选项的操作优先级要高于"-l",即先搜索出反转行,再输出包含这些反转行的文件)

使用"|"可以实现or逻辑,如何实现AND逻辑?

grep 'paul' /etc/motd | grep 'franc,ois'

将搜索出同时包含"paul"和"franc,ois"的所有行。

如何同时搜索文件和标准输入?
只需使用"-"代替标准输入的文件名即可:

cat /etc/passwd | grep 'alain' - /etc/motd

正则表达式中如何表达出回文结构?(注:回文结构表示正读和反读的结果是一样的,例如12321,abcba)
可以使用反向引用来实现。例如,一个4字符的结构使用BRE来实现:

grep -w -e '\(.\)\(.\).\2\1' file

它可以匹配单词"radar"或"civic"。 Guglielmo Bondioni提出了一个正则表达式,可以搜索长达19个回文结构的字符串,其中使用了9个子表达式和9个反向引用。因为BRE或ERE最多只支持9个反向引用。

grep -E -e '^(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?).?\9\8\7\6\5\4\3\2\1$' file

为何反向引用会失效?

echo 'ba' | grep -E '(a)\1|b\1'

这不会输出任何内容,因为左边的表达式"(a)\1"无法匹配,因为输入数据中没有"aa",因此右边的"\1"无法引用任何内容,意味着将不匹配任何东西。(此例中右边表达式仅在左边表达式成功匹配时才能生效。)
注:经测试,即使左边表达式能匹配上,右边表达式中引用左边的分组时也无效。例如"echo 'baaca' | grep -E '(a)\1|c\1'"可以匹配大其中的"aa",但却匹配不到"ca"。

grep如何跨行匹配?
标准的grep无法实现该功能,因为它是基于行读取的。因此,仅仅使用字符类"[:space:]"无法如你想象中那样匹配换行符。
GNU的grep有一个选项"-z",它可以处理使用"\0"结尾的行。因此,可以匹配输入数据中的换行符,但通常很可能在输出结果时,输出的是所有内容而不仅是被匹配的行,因此经常需要结合输出控制选项如"-q"来使用。例如:

printf 'foo\nbar\nabc' | grep -z 'foo[[:space:]]\+bar' printf 'foo\nbar\nabc' | grep -z -q 'foo[[:space:]]\+bar'

如果这还不满足需求,可以将输入数据进行格式转换然后交给grep,或者使用其他工具替代grep,如"sed"、"awk"、"perl"或其他很多工具都能跨行操作。

What do 'grep', 'fgrep', and 'egrep' stand for?
The name 'grep' comes from the way line editing was done on Unix. For example, 'ed' uses the following syntax to print a list of matching lines on the screen:

global/regular expression/print g/re/p

'fgrep' stands for Fixed 'grep'; 'egrep' stands for Extended 'grep'.

5 Known Bugs(已知的一些bug)

当"{n,m}"指定的重复次数很多时,将导致grep消耗大量内存。此外,越模糊的正则表达式消耗的时间和空间越多,也会让grep消耗大量内存。 反向引用的功能非常慢,因此可能会消耗大量时间。 (注:递归搜索时,也会消耗巨量的内存,很容易提示内存溢出错误而提前退出。)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/13491.html