未分类 · 2015年4月16日

大话 find grep and xargs

grep全称是Global Regular Expression Print,
-E, –extended-regexp PATTERN 是一个可扩展的正则表达式(缩写为 ERE)
-L, –files-without-match 只打印不匹配FILEs 的文件名
-l, –files-with-matches 只打印匹配FILES 的文件名
-c, –count 只打印每个FILE 中的匹配行数目
-l, –files-with-matches 只打印匹配FILES 的文件名
-n, –line-number 输出的同时打印行号 显示匹配行及行号
杂项:
-s, –no-messages 不显示错误信息
-v, –invert-match 选中不匹配的行
pattern正则表达式主要参数:
\:忽略正则表达式中特殊字符的原有含义。
^:匹配正则表达式的开始行。
$: 匹配正则表达式的结束行。
\<:从匹配正则表达式的行开始。 \>:到匹配正则表达式的行结束。
[ ]:单个字符,如[A]即A符合要求 。
[ – ]:范围,如[A-Z],即A、B、C一直到Z都符合要求 。
。:所有的单个字符。
* :有字符,长度可以为0。
eg
root@evankali:~# ls
1 12 Desktop 公共 模板 视频 图片 文档 下载 音乐
显示所有以1开头的文件中包含test的行
root@evankali:~# grep ‘test’ 1*
1:test
12: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′就可以了。
5.grep命令使用复杂实例
假设您正在’/usr/src/linux/Doc’目录下搜索带字符串’magic’的文件:
$ grep magic /usr/src/linux/Doc/*
sysrq.txt:* How do I enable the magic SysRQ key?
sysrq.txt:* How do I use the magic SysRQ key?
其中文件’sysrp.txt’包含该字符串,讨论的是 SysRQ 的功能。
默认情况下,’grep’只搜索当前目录。如果此目录下有许多子目录,’grep’会以如下形式列出:
grep: sound: Is a directory
这可能会使’grep’的输出难于阅读。这里有两种解决的办法:
明确要求搜索子目录:grep -r
或忽略子目录:grep -d skip
如果有很多输出时,您可以通过管道将其转到’less’上阅读:
$ grep magic /usr/src/linux/Documentation/* | less
这样,您就可以更方便地阅读。
有一点要注意,您必需提供一个文件过滤方式(搜索全部文件的话用 *)。如果您忘了,’grep’会一直等着,直到该程序被中断。如果您遇到了这样的情况,按 ,然后再试。
下面还有一些有意思的命令行参数:
grep -i pattern files :不区分大小写地搜索。默认情况区分大小写,
grep -l pattern files :只列出匹配的文件名,
grep -L pattern files :列出不匹配的文件名,
grep -w pattern files :只匹配整个单词,而不是字符串的一部分(如匹配’magic’,而不是’magical’),
grep -C number pattern files :匹配的上下文分别显示[number]行,
grep pattern1 | pattern2 files :显示匹配 pattern1 或 pattern2 的行,
grep pattern1 files | grep pattern2 :显示既匹配 pattern1 又匹配 pattern2 的行。
这里还有些用于搜索的特殊符号:
\< 和 \> 分别标注单词的开始与结尾。
例如:
grep man * 会匹配 ‘Batman’、’manic’、’man’等,
grep ‘\<man’ * 匹配’manic’和’man’,但不是’Batman’,
grep ‘\<man\>’ 只匹配’man’,而不是’Batman’或’manic’等其他的字符串。
‘^’:指匹配的字符串在行首,
‘$’:指匹配的字符串在行尾,
*****************
find
find <指定目录> <指定条件> <指定动作>
所要搜索的目录及其所有子目录。默认为当前目录。find默认递归指定目录。目录可以有多个,目录之间要用空格分开
find /etc /tmp /root -name passwd
1.2 <指定条件>:
所要搜索的文件的特征。
[1]根据文件名查找
-name 按照文件名查找
-iname 根据文件名查找,但是不区分大小写
-prune 不在当前指定的目录中查找
-depth 在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找
[2]根据文件所属用户和组来查找文件
-user 按照文件属主来查找文件
$find / -user fred //查找在系统中属于FRED这个用户的文件
-group 按照文件所属的组来查找文件
find / -group cat //查找在系统中属于group组名cat的文件
[3]根据uid 和 gid来查找用户
-uid
find /tmp -uid 500 //查找uid是500 的文件
-gid
find /tmp -gid 1000 // 查找gid是1000的文件
[4]-a,-o,-not的使用
-a 连接两个不同的条件(两个条件必须同时满足)
find /tmp -name “*.sh” -a -user root
-o 连接两个不同的条件(两个条件满足其一即可
find /tmp -name “*.sh” -o -user root
-not 对条件取反的
find /tmp -not -user root
[5]根据文件时间戳的相关属性来查找文件
-atime 最近一次访问时间 单位:天
-mtime 最近一次内容修改时间 单位:天
-ctime 最近一次属性修改时间 单位:天
-amin 最近一次访问时间 单位:分钟
-mmin 最近一次内容修改时间 单位:分钟
-cmin 最近一次属性修改时间 单位:分钟
-newer file1 ! file2 查找更改时间比文件file1新但比文件file2旧的文件
find /tmp -atime +5 //表示查找在五天内没有访问过的文件
find /tmp -atime -5 //表示查找在五天内访问过的文件
[6]根据文件类型来查找文件
-type 查找某一类型的文件
文件类型:
f 普通文件
d 目录
l 符号链接文件
c 字符设备文件
p 管道文件
b 块设备文件
s socket文件
find /tmp -type s
[7]根据大小来查找文件
-size n[c] 查找文件长度为n块的文件,带有c时表示文件长度以字节计
find /tmp -size 2M //查找在/tmp 目录下等于2M的文件
find /tmp -size +2M //查找在/tmp 目录下大于2M的文件
find /tmp -size -2M //查找在/tmp 目录下小于2M的文件
find . -size +1000000c //在当前目录下查找文件长度大于1 M字节的文件
find / -empty //查找在系统中为空的文件或者文件夹
[8]根据文件权限查找文件
-perm
#find /tmp -perm 755 //查找在/tmp目录下权限是755的文件
#find /tmp -perm +222 //表示只要有一类用户(属主,属组,其他)的匹配写权限就行
#find /tmp -perm -222 //表示必须所有类别用户都满足有写权限
[10]-nouser和-nogroup
-nogroup 查找无有效所属组的文件,即该文件所属的组不存在
-nouser 查找无有效属主的文件
#find / -nogroup -a -nouser //在整个系统中查找既没有属主又没有属组的文件(这样的文件通常是很危险的,作为系统工程师的我们应该及时清除掉)
find / -nouser //查找在系统中属于作废用户的文件
1.3 <指定动作>:
对搜索结果进行特定的处理。
-print //默认情况下的动作
-ls //查找到后用ls 显示出来
-ok [commend] //查找后执行命令的时候询问用户是否要执行
-exec [commend] //查找后执行命令的时候不询问用户,直接执行
注意-ok和-exec命令将命令行上后续的参数作为他们参数的一部分,直到被\;序列终止。魔术字符串{}是-ok和-exec命令的一个特殊类型的参数,它将被当前文件的完整路径取代。
##常用例子
find /tmp -atime +30 –exec rm –rf {} \; //删除查找到的超过30天没有访问过文件
这里要注意{ }的使用:替代查找到的文件
find /tmp -name “*.old” | xargs chmod 700
2 命令举例
搜索/etc目录下的文件名包含del的文件。
$find /etc -name ‘*del*’
系统查找到”config.py”文件后即时在屏幕上显示”config.py”文件信息。
$find . -name “config.py” -ls
搜索当前目录中,所有过去10分钟中更新过的普通文件。如果不加-type f参数,则搜索普通文件+特殊文件+目录。
$ find . -type f -mmin -10
**********************
xargs
xargs – build and execute command lines from standard input
在使用find命令的-exec选项处理匹配到的文件时, find命令将所有匹配到的文件一起传递给exec执行。但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现溢出错误。错误信息通常是“参数列太长”或“参数列溢出”。这就是xargs命令的用处所在,特别是与find命令一起使用。
find命令把匹配到的文件传递给xargs命令,而xargs命令每次只获取一部分文件而不是全部,不像-exec选项那样。这样它可以先处理最先获取的一部分文件,然后是下一批,并如此继续下去。
在有些系统中,使用-exec选项会为处理每一个匹配到的文件而发起一个相应的进程,并非将匹配到的文件全部作为参数一次执行;这样在有些情况下就会出现进程过多,系统性能下降的问题,因而效率不高;
而使用xargs命令则只有一个进程。另外,在使用xargs命令时,究竟是一次获取所有的参数,还是分批取得参数,以及每一次获取参数的数目都会根据该命令的选项及系统内核中相应的可调参数来确定。
来看看xargs命令是如何同find命令一起使用的,并给出一些例子。
下面的例子查找系统中的每一个普通文件,然后使用xargs命令来测试它们分别属于哪类文件
#find . -type f -print | xargs file
./.kde/Autostart/Autorun.desktop: UTF-8 Unicode English text
./.kde/Autostart/.directory: ISO-8859 text\
……
在整个系统中查找内存信息转储文件(core dump) ,然后把结果保存到/tmp/core.log 文件中:
$ find / -name “core” -print | xargs echo “” >/tmp/core.log
上面这个执行太慢,我改成在当前目录下查找
#find . -name “file*” -print | xargs echo “” > /temp/core.log
# cat /temp/core.log
./file6
在当前目录下查找所有用户具有读、写和执行权限的文件,并收回相应的写权限:
# ls -l
drwxrwxrwx 2 sam adm 4096 10月 30 20:14 file6
-rwxrwxrwx 2 sam adm 0 10月 31 01:01 http3.conf
-rwxrwxrwx 2 sam adm 0 10月 31 01:01 httpd.conf
# find . -perm -7 -print | xargs chmod o-w
# ls -l
drwxrwxr-x 2 sam adm 4096 10月 30 20:14 file6
-rwxrwxr-x 2 sam adm 0 10月 31 01:01 http3.conf
-rwxrwxr-x 2 sam adm 0 10月 31 01:01 httpd.conf
用grep命令在所有的普通文件中搜索hostname这个词:
# find . -type f -print | xargs grep “hostname”
./httpd1.conf:# different IP addresses or hostnames and have them handled by the
./httpd1.conf:# VirtualHost: If you want to maintain multiple domains/hostnames
on your
用grep命令在当前目录下的所有普通文件中搜索hostnames这个词:
# find . -name \* -type f -print | xargs grep “hostnames”
./httpd1.conf:# different IP addresses or hostnames and have them handled by the
./httpd1.conf:# VirtualHost: If you want to maintain multiple domains/hostnames
on your
注意,在上面的例子中, \用来取消find命令中的*在shell中的特殊含义。
find命令配合使用exec和xargs可以使用户对所匹配到的文件执行几乎所有的命令。
四、find 命令的参数
下面是find一些常用参数的例子,有用到的时候查查就行了,像上面前几个贴子,都用到了其中的的一些参数,也可以用man或查看论坛里其它贴子有find的命令手册
1、使用name选项
文件名选项是find命令最常用的选项,要么单独使用该选项,要么和其他选项一起使用。
可以使用某种文件名模式来匹配文件,记住要用引号将文件名模式引起来。
不管当前路径是什么,如果想要在自己的根目录$HOME中查找文件名符合*.txt的文件,使用~作为 ‘pathname’参数,波浪号~代表了你的$HOME目录。
$ find ~ -name “*.txt” -print
想要在当前目录及子目录中查找所有的‘ *.txt’文件,可以用:
$ find . -name “*.txt” -print
想要的当前目录及子目录中查找文件名以一个大写字母开头的文件,可以用:
$ find . -name “[A-Z]*” -print
想要在/etc目录中查找文件名以host开头的文件,可以用:
$ find /etc -name “host*” -print
想要查找$HOME目录中的文件,可以用:
$ find ~ -name “*” -print 或find . -print
要想让系统高负荷运行,就从根目录开始查找所有的文件。
$ find / -name “*” -print
如果想在当前目录查找文件名以两个小写字母开头,跟着是两个数字,最后是.txt的文件,下面的命令就能够返回名为ax37.txt的文件:
$find . -name “[a-z][a-z][0–9][0–9].txt” -print
还有一些不错用法
第一种方法
首先,举个最简单的例子,在阅读代码过程中我们经常需要查看某个函数的定义,但是一般开源项目代码规模都相当庞大,此时你就可以如下使用find+grep轻松查找到该函数的定义,譬如,我想在php源码中搜索is_array方法的定义,如下:
[root@]# find . -name ‘*.c’ -exec grep -Hna ‘is_array’ {} \;
./basic_functions.c:2540:ZEND_BEGIN_ARG_INFO(arginfo_is_array, 0)
./basic_functions.c:3049: PHP_FE(is_array, arginfo_is_array)
./type.c:283:/* {{{ proto bool is_array(mixed var)
./type.c:285:PHP_FUNCTION(is_array)
这里需要注意两点: 1. find使用-exec时“\;”是必备参数,如下两种方法都会导致“find: missing argument to `-exec’”,其中第一个命令报错是因为确实缺少“;”,而第二个命令报错是因为在shell中执行语句时“;”被认为是结束符,而不是-exec的参数,故使用时必须对其进行转义。
[root@]# find . -name ‘*.c’ -exec grep -Hna ‘is_array’ {}
find: missing argument to `-exec’
[root@]# find . -name ‘*.c’ -exec grep -Hna ‘is_array’ {} ;
find: missing argument to `-exec’
[root@d]# find –help
actions: -delete -print0 -printf FORMAT -fprintf FILE FORMAT -print
-fprint0 FILE -fprint FILE -ls -fls FILE -prune -quit
-exec COMMAND ; -exec COMMAND {} + -ok COMMAND ;
-execdir COMMAND ; -execdir COMMAND {} + -okdir COMMAND ;
2. 如上例,笔者在使用grep时添加了-Hna,其分别输出文件路径,行号,及相应的文本内容:
[root@]# grep –help
-n, –line-number print line number with output lines
–line-buffered flush output on every line
-H, –with-filename print the filename for each match
-a, –text equivalent to –binary-files=text
第二种方法
如果针对查看项目查看源码的需求,那么在服务器上安装配置好ctags工具来配合vim,将是完美方案,请参考《Sublime Text 2安装Ctags插件》相似原理在Linux上安装配置即可,强烈技术流的同学使用该方法。
linux 用grep命令查找etc目录下含有字符串“wl0505”的文件有什,并记录
find / -name “*.*” | xargs grep “wl0505” >>/home/filename
*.*是文件名和扩展名,>>是把结果重定向到后面路径的文件中去,不在终端上显示了。
find /etc -name “*” |xargs grep “wl0505” > ~/thefile
grep -rn wl0505 /etc/*
一条命令就可以了
Linux中的find与grep命令对查找到的文件怎处理
find xxxx *.wav >file.list | aplay xxxx -r file.list
大概思路 find 结果进入文件,管道让aplay从文件获取播放列表
ls -ls |grep xxx |vi
或者干脆写个读写文件的bash shell脚本
建议看看 awk sed unixshell程序设计,会对你有启发
在某个路径下查找所有包含“in”字符串的文件。
find /root/ -name "*" | xargs grep "in"
find . -name ff -exec rm {} \; #删除当前目录及其子目录下所有文件名为ff的文件
https://blog.robotshell.org/2010/powerful-find/
http://ltblog.blog.51cto.com/1263616/845691
linux grep命令
http://andyss.blog.51cto.com/315552/139723
linux-find【递归搜索文件名】
http://blog.csdn.net/gexiaobaohelloworld/article/details/8206889
Linux文件查找命令find和xargs详解

g