命令grep、egrep、fgrep中的匹配模式

grep 用来在文件中匹配、查找。其作用就像是一个小型的“搜索引擎”。

grep的用法点滴

  • grep hello # 查找匹配到的行
  • grep -v hello # 查找不匹配的行, v=invert
  • grep -c hello # 查找匹配到的行的数目, c=count
  • grep -i hello # 查找时忽略大小写, i=ignore
  • grep -C 3 hello # 输出时输出匹配行的上下文,C=Context
  • grep -B 3 hello # 输出匹配行前面的上下文, B=Before
  • grep -A 3 hello # 输出匹配行后面的上下文, A=After
  • grep -r work/ hello # 递归搜索目录下的所有文件, r=recursive

更多用法及示例敬请参见后续文章。

匹配模式

搜索引擎也好,匹配查询也好,现实中的提问也好,很重要的一点是描述清楚你的问题。

对于命令grep的使用来说,其中一个重要方面就是正确描述你要查找的内容。这被称为 pattern 。

  • 默认的grep其实相当于grep -G
    • 采用 Basic Regular Expression
  • egrep相当于grep -E
    • 采用 Extended Regular Expression
  • fgrep 相当于grep -F
    • 采用 Fixed String
  • 还有一个不怎么常用的grep -P
    • 采用 Perl Regular Expression

默认的grep用的匹配方法被称作Basic Regular Expression。

Regular Expression

关于正则表达式,这里不作详细介绍。只是其间具有特殊含义的几个字符:

( ) { } | + ? [ ] . ^ $ \

Shell命令中的regular expression很多时候默认指的都是Basic Regular Expression。

在Basic Regular Expression中,下面几个字符则被当作普通字符。

( ) { } | + ?

如果需要它们用作正则表达式里的特殊字符,则需要在这些字符前面加上反斜线才行。

下面的例子可以说明:

% echo "hello grep, egrep, fgrep. (tcler)" | grep -o "(tcler)"
(tcler)
% echo "hello grep, egrep, fgrep. (tcler)" | grep -o -E "(tcler)"
tcler
% echo "hello grep, egrep, fgrep. (tcler)" | grep -o "\(tcler\)"
tcler

fgrep = Fixed and Fast

grep和egrep的区别,很多时候并不是很重要。毕竟很多时候我们需要查找的字符串都比较简单。这时,非常值得一提的其实是fgrep这个命令,它其实相当于grep -F

F可以看作是Fixed的简写,因为这种情况下,使用的匹配方法不再是正则表达式匹配,而是要求字符完全一样的字符串查找。

字符串查找比正则表达式的速度是要快很多的。因此,也不妨理解为FFast的意思。

用一个382MB大小的文件简单测试,grep用时14.44妙,fgrep则只用了0.37秒。

 % time grep "Thank you" a_file_382MB
13.303u 0.631s 0:14.44 96.4%    0+0k 778016+0io 0pf+0w
% time fgrep "Thank you" a_file_382MB
0.260u 0.097s 0:00.37 94.5%     0+0k 0+0io 0pf+0w

在递归搜索目录的时候,这种速度差异将更加明显。