grep技巧(-r):在某一目录下递归[所有子目录]查找某一字串:+文件路径

时间:2021-06-27 14:33:18
转自: http://zhumeng8337797.blog.163.com/blog/static/1007689142011350151438/

在某一目录下递归[所有子目录]查找某一字串:
grep -r “字串” 目录名

就是加一个-r参数,请看man page:

-R, -r, –recursive
Read all files under each directory, recursively; this is equivalent to the -d recurse option.


 grep -Rl "3306" * 这句可以显示在哪个文件里包含3306  
 grep -REn "3306" * 可以显现文件名,行数 
  R 表示递归,就是在当前目录找不到就去子目录找 
E 表示把文件名也打印出来 
n 打印此行在文件中的位置。

Unix grep家族包括grep,egrepfgrepGrep的命令在文件中搜索正则表达式,并打印所有包含这些表达式的行。Egrepfgrep命令只跟grep有很小的不同。Egrepgrep的扩展,支持更多的RE元字符。Fgrep就是fixed grep 或者 fast grep,它们把所有的字母都看作单词。这就是说,正则表达式的元字符不再特殊――他们只表示其自身的字母意思。


Grep的意思是“全面搜索正则表达式并把找到的行打印出来(global search regular expression(RE) and print out the line)。

Grep的正则表达式元字符集(基本集)

元字符

功能

例子

匹配什么

^

锚定行的开始

/^love/

匹配所有以love开头的行

$

锚定行的结束

/love$/

匹配所有以love 结束的行

.

匹配一个字符

/l..e/

匹配这样的行,这些行包含这样的字符:第一个字符是l,紧跟着两个字符,然后是e

*

代表0个或多个先前字符

/*love/

匹配所有这样的行,有0个或多个空格,空格后跟着love

[]

匹配字符组中的一个字符

/[Ll]ove/

匹配所有包含love或者Love的行

[^]

匹配一个不在范围内的字符

/[^A-Z]ove/

<

锚定单词的开始

<love

匹配所有这样的行,这些行包含以love开头的单词(vigrep支持这个功能)

>

锚定单词的结束

Love>

匹配所有这样的行,这些行包含以love结束的单词(vigrep支持这个功能)

(..)

标记后面用到的匹配字符

/(love)able1rs/

最多可以使用9个标签。第一个标签是模板最左边的部分。在本例子中,模板love保存的标签为1,后面的1指得就是love;本例子搜索的是这样的行,这些行包含这样的字符,在Loveabel后面跟着lovers

x{m}

M次复制字符x

x{m,}

至少m次复制字符x

x{m,n}

至少m次,至多n次复制字x

w

文字和数字字符,[A-Za-z0-9]

Lw*e

匹配一个l字符,紧跟着0个或多个文字或数字字符,然后是e

W

同上

b

单词分界线

bloveb

仅仅匹配单词love

扩展集(用于egrepgrep-E

+

匹配一个或者多个先前字符

[a-z]+ove

匹配一个或者多个小写字符且后面是ove的,

?

匹配0个或者多个先前字符

Lo?ve

P匹配l后面有一个或者没有o,然后是ve

a|b|c

匹配abc

Love|hate

匹配lovehate其中一个

()

字符组

Love(able|rs)(ov)+

匹配loveablelovers,匹配一个或多个ov

(…)(…)12

标记匹配字符串

(love)ing

标签标记出寄存器的一部分,并稍后替换模板。该模板叫做1,并可反复引用。在表达式中最多可以使用9个这样的标签。例如,模板love被保存在寄存器1中并稍后替换标签叫做1

x{m}

重复字符X,m次,至少m,或者m次和n次之间。

x{m,}

x{m,n}



Grep和退出状态


Grep命令在shell教本中非常有用,因为它通过返回一个退出状态值来说明是否找到了你要搜索的模板或者文件。如果模板找到,grep返回状态值0,表示成功;如果无法找到模板,则返回退出状态值1;如果文件无法找到,就返回退出状态值2linuxunix使用的其他搜索程序并不返回退出状态值,只在出现语法错误的时候返回错误)。

[posftp@SZTrade posftp]$ grep 'john' /etc/passwd

[posftp@SZTrade posftp]$ echo $?

1

[posftp@SZTrade posftp]$echo $status

Grep与选项

Gun grep 选项

-b 在搜索到的行为的前面打印该行所在的块号码。该功能在通过内容定位块的号码时非常有用.

-c 只显示有多少行匹配,而不具体显示匹配的行

 -h 不显示文件名

 -I 在字符串比较的时候忽略大小写

 -l 只显示包含匹配模板的行的文件名清单,不同项目之间用换行符分割

 -n 在每一行前面打印该行在文件中的行数

-s 静默工  作,除非出现错误信息,否则不打印任何信息,这个功能在检测退出状态的时候有用

 -v 反检索,只显示不匹配的行

-w 如果被>引用,就把表达式做为一个单词搜索只在grep中 有效(不是所有版本的grep都支持该特性,sco unixgrep就不支 持)

所有gun*都可以使用的grep选项(-G,-E-F

选项

功能

-#

表示同时显示匹配上下的#行,例如:grep -2 pattern filename 表示同时显示匹配行上下各两行

-A#,--after-context=#

在匹配指定的内容的行打印完毕后,再打印一行#号

-B#,--before-context=#

在匹配模板的行的前面打印一行#号

-C,--context

相当于选项-2,在匹配行的前后各打印2行空行

-V,--version

显示包括bug报告在内的版本信息

-b,--byte-offset

在每一行前面打印字符偏移量

-c,--count

打印每个文件匹配行的个数

-e
PATTERN,--regexp=PATTERN

使用PATTERN的字面意思作为模板,在模板以“-”开头的时候非常有用

-f
FILE,--file=FILE

FILE中提取模板。空文件中包含0个模板,所有什么也不匹配

-h,--no-filename

当多个文件匹配时候,不显示匹配文件名前缀

-i,--ignore-case

在模板和输入文件中都忽略大小写差别

-L,--files-without-match

打印不匹配模板的文件名清单

-I,--files-with-matches

打印匹配模板的文件名清单

-n,--line-number

在匹配的行前面打印行号

-q,--quit

取消标准输出,跟-n功能是一样的

-s,--silent

不显示关于不存在或者无法读取文件的错误信息

-v,--revert-match

打印不匹配模板的行

-w,--word-regexp

只打印以单词形式匹配模板的行,模板可以是包含数字,字符和下划线的字符集

-x,--line-regexp

只打印正行匹配的行

-y

用法同-i

-U,--binary

把文件作为二进制文件,这个选项只在MS-DOSMS-Windows中被支持

-u,--unix-byte-offsets

按照unix风格报告字符偏移量。只在-b选项同时被使用的时候才有效。这个选项只在MS-DOSMS-Windowns中被支持

例子:

grep Tom /etc/passwd

在文件/etc/passwd中搜索模板Tom,如果成功,搜索的行将显示在屏幕上。

Ps aux | grep root

Ps命令输出(pa aux显示系统中运行的所有进程)被发送给grep,所有包含root的行都将被打印。

正则grep实例(grep ,grep –G

grep NW datafile

grep –G NW datafile

打印文件datafile中包含正则表达式NW的行

grep NW d*

打印所有以开头的文件中且包含正则表达式NW的行。Shell扩展d*表示所有以d开头的文件。

Grep ‘^n’ datafile

打印所有以n开头的行,^表示锚定行的开头。

Grep TB Savage datafile

因为第一个参数是模板,其他的参数是文件名,所以grep将在文件Savagedatafile中搜索TB.

Grep ‘TB Savage’ datafile

打印所有包含模板TB Savage的行。如果没有引用(在本例子中,单引号和双引号的作用是一样的)。TBSavage之间的空格将导致grep在文件Savagedatafile中搜索TB

Gun grep选项例子

grep -2 patricia datafile

打印匹配patricia的行以及该行的上下各两行。

Grep –C patricia datafile

选项-C跟选项-2的功能是一样的。

Grep –A 2 patricia datafile

Grep打印匹配patricia的行已经该行的下两行。

Grep –b ‘[abc]’ datafile

选项-b使得grep在打印每一行前打印字符偏移量。



grep的一般格式为: 
               grep [选项] pattern [文件]

单引号和双引号:
1)在grep命令中输入字符串参数时,最好将其用双引号括起来。例如:“my strings”,这样做有两个原因,一个是防止被误会是shell命令,一个是可以用来查找多个单词组成的字符串,就如这个例子中的“my strings”
   2)在调用变量的时候,也应该使用双引号,例如:grep “$MYNAME”
   3)在调用模式匹配(正则表达式)时,应该使用单引号

egrep和grep
egrep:  grep 的扩充版本改良了许多传统 grep 不能或不便的操作比方说
- grep 
之下不支持 ?  + 这两种 modifier,  egrep 则可
- grep 
不支持 a|b  (abc|xyz) 这类"或一"比对 egrep 则可
- grep 
在处理 {n,m} 需用 \{  \} 处理 egrep 则不需
         所以egrep就不用grep... ^_^ ,可以加选项 -E 来使grep具有egrep的功能
   关于egrep和grep在正则方面的区别,请参考文章各种工具之正则表达式语法比较

返回状态:匹配:0             不匹配:1        文件不可访问或语法错误:2

◎参数 
     1:-A NUM :除了列出符合行之外,并且列出NUM行。 ex:    $ grep -A 1 panda file 

     2:-B NUM     与 -A NUM 相对,显示除符合行之外,并显示在它之前的NUM行。         

     3:-C [NUM],     列出符合行之外并列出上下各NUM行,预设值是2。 可以直接写为 -n,如:grep -5 pattern filename同时显示匹配行的上下5行。
               
     4:-c, --count 不显示符合样式行,只显示符合的总行数。 若再加上-v,显示不符合的总行数。 

     5.   -f file 读取文件file,该文件的每一行都包含一个模式,从输入中查找匹配每个模式的行 

     6.   -r 文件夹 递归的搜索该文件夹中的目录,处理目录中的每个文件

     7.   -h, --no-filename    当搜索多个文件(-r 文件夹),在输出时不显示文件路径及名称。 注:不加-h,就是默认的时候,是显示文件名的,若是只是一个文件,则默认不显示(一个的话你肯定指定了,你都知道了还显示什么呢?)

     8.   -I (小写字母 l ) 只显示包含匹配的文件的文件名,且无论匹配多少次,只显示文件名一次。若是 -L,则是显示不匹配的文件名

     9.   -i, --ignore-case        忽略大小写                
  
     0.   -n, --line-number 在匹配的每行前,标上行号。 
      
     1.   -q, --quiet, --silent 不发送任何内容到标准输出,仅设置退出码

     2.   -v, --invert-match 显示不匹配的行。 
                    
     3.   -w, --word-regexp 完全匹配模式,完全匹配该"字"的行才会被列出。 

     4.   -x, --line-regexp     整行匹配,完全符合该"行"的行才会被列出

正则表达式:

^ 匹配正则表达式的开始行 
$ 匹配正则表达式的结束行 
< 从匹配正则表达式的行开始 
> 到匹配正则表达式的行结束 
[ ] 单个字符;如[A] 即A符合要求 
[ - ] 范围 ;如[A-Z]即A,B,C一直到Z都符合要求 
. 所有的单个字符 
* 所有字符,长度可以为0

注意:有必要参考上文提到的各种工具之正则表达式语法比较 特别是grep和egrep还不太一样。

实例:

$ ls -l | grep '^a'
通过管道过滤ls -l输出的内容,只显示以a开头的行。
$ grep 'test' d*
显示所有以d开头的文件中包含test的行。
$ grep 'test' aa bb cc
显示在aa,bb,cc文件中匹配test的行。
$ grep '[a-z]\{5\}' aa
显示所有包含每个字符串至少有5个连续小写字符的字符串的行。
$ grep 'w\(es\)t.*\1' aa
如果west被匹配,则es就被存储到内存中,并标记为1,然后搜索任意个字符(.*),这些字符后面紧跟着另外一个es(\1),找到就显示该行。如果用egrep或grep -E,就不用"\"号进行转义,直接写成'w(es)t.*\1'就可以了。

[root@bogon yum.repos.d]# find /etc/  -exec grep  -ln  'alias ls'  {} \;
/etc/profile.d/colorls.sh
/etc/profile.d/colorls.csh
/etc/lftp.conf
[root@bogon yum.repos.d]# find /etc/  -exec grep  -n  'alias ls'  {} \;
20:     alias ls='ls --color=tty' 2>/dev/null
30:alias ls 'ls --color=tty'
[root@bogon yum.repos.d]# find /etc/  -exec grep  -nR  'alias ls'  {} \;
/etc/profile.d/colorls.sh:20:   alias ls='ls --color=tty' 2>/dev/null
/etc/profile.d/colorls.csh:30:alias ls 'ls --color=tty'