目录

find

xargs


find

find  path  -options  [ -print ]  [ -exec  -ok  command ]  {} \;

占位符机制,这种机制中的占位符是“{}”。

-name  按照文件名查找文件

-perm   按照文件权限查找文件
-prune  忽略目录
-user    按照文件属主查找
-group   按照文件所属的组来查找文件
-mtime -n +n  按照文件的更改时间来查找文件,-n表示文件更改时间距现在n天以内,+n表示文件更改时间距现在n天以前
-nogroup    查找无有效属组的文件、即该文件所属的组在/etc/groups中不存在
-nouser    查找无有效属主的文件,即该文件的属主在/etc/passwd中不存在
-newfile file1 ! file2  查找更改时间比文件file1新但比文件file2旧的文件
-type      查找某一类型的文件,诸如:
b       块设备文件
d       目录
c        字符设备文件
p        管道文件
l         符号链接文件
f         普通文件
-size  n[c]    查找文件长度为n块的文件,带有c时表示文件长度以字节计
-depth         在查找文件是,首先查找当前目录只的文件,然后再在其子目录中查找
-fstype        查找位于某一类型文件系统中的文件,这些文件系统类型通常可以在配置文件/etc/fstab中找到
-mount       在查找文件时不跨越文件系统mount点
-follow        如果find命令遇到符号链接文件,就跟踪至链接所指向的文件
-cpio           对匹配的文件使用cpio命令,将这些文件备份到磁带设备中。
在$HOME目录下查找txt文件并打印
find ~ -name "*.txt" -print
在当前目录下查找txt文件并打印
find . -name "*.txt" -print

查找系统中的每一个普通文件,并用xargs命令来测试它们分别属于哪类文件:

[root@localhost script]# find /home -type f |xargs file
查找大于10M并列出详细信息
#-size n[c]查找文档长度为n块的文档 有[c]表示文档长度以字节计算
#-exec  command  {} \;   将查到的文档执行command操作,{} 和 \;之间有空格
#-ok 和-exec相同,只是在操作前要询用户
[root@localhost script]# find ~ -size +10000000c |xargs ls -l
[root@localhost script]# find ~ -size +10000000c -exec ls -l {} \;
[root@localhost script]# find ~ -size +10000000c -ok ls -l {} \;
查找用户mysql的文件
[root@localhost script]# find / -user mysql
查找包含if行的所有文件
[root@localhost script]# find . -type f |xargs grep "if"
查找以大写字母开头的文件
[root@localhost script]# find ~ -name "[A-Z]*"
在当前目录下查找以f开始的文件,并把结果输出到dddddd中
[root@localhost script]# find . -name "f*"  -fprint dddddd
查找以f或以c开头的文件
[root@localhost script]# find . -name "f*" -o -name "c*"
find   /  -nouser             #查找在系统中属于作废用户的文档
find   /  -empty              # 查找在系统中为空的文档或文档夹
find   /  -mmin   -5          # 查找在系统中最后5分钟里修改过的文档
find   /  -mtime  -1          #查找在系统中最后24小时里修改过的文档

   下面给出find命令的主要应用示例:
   /> ls -l     #列出当前目录下所包含的测试文件
   -rw-r--r--. 1 root root 48217 Nov 12 00:57 install.log
   -rw-r--r--. 1 root root      37 Nov 12 00:56 testfile.dat
   -rw-r--r--. 1 root root 10530 Nov 11 23:08 test.tar.bz2
   -rw-r--r--. 1 root root     183 Nov 11 08:02 users
   -rw-r--r--. 1 root root     279 Nov 11 08:45 users2
   1. 按文件名查找:
   -name:  查找时文件名大小写敏感。
   -iname: 查找时文件名大小写不敏感。
   #该命令为find命令中最为常用的命令,即从当前目录中查找扩展名为.log的文件。需要说明的是,缺省情况下,find会从指定的目录搜索,并递归的搜索其子目录。
   /> find . -name "*.log"
    ./install.log
   /> find . -iname U*          #如果执行find . -name U*将不会找到匹配的文件
   users users2
   2. 按文件时间属性查找:
   -atime  -n[+n]: 找出文件访问时间在n日之内[之外]的文件。
   -ctime  -n[+n]: 找出文件更改时间在n日之内[之外]的文件。
   -mtime -n[+n]: 找出修改数据时间在n日之内[之外]的文件。
   -amin   -n[+n]: 找出文件访问时间在n分钟之内[之外]的文件。
   -cmin   -n[+n]: 找出文件更改时间在n分钟之内[之外]的文件。
   -mmin  -n[+n]: 找出修改数据时间在n分钟之内[之外]的文件。
   /> find -ctime -2        #找出距此时2天之内创建的文件
   .
   ./users2
   ./install.log
   ./testfile.dat
   ./users
   ./test.tar.bz2
   /> find -ctime +2        #找出距此时2天之前创建的文件
   没有找到                     #因为当前目录下所有文件都是2天之内创建的
   /> touch install.log     #手工更新install.log的最后访问时间,以便下面的find命令可以找出该文件
   /> find . -cmin  -3       #找出修改状态时间在3分钟之内的文件。
   install.log

   3. 基于找到的文件执行指定的操作:
   -exec: 对匹配的文件执行该参数所给出的shell命令。相应命令的形式为'command' {} \;,注意{}和\;之间的空格,同时两个{}之间没有空格
   -ok:   其主要功能和语法格式与-exec完全相同,唯一的差别是在于该选项更加安全,因为它会在每次执行shell命令之前均予以提示,只有在回答为y的时候, 其后的shell命令才会被继续执行。需要说明的是,该选项不适用于自动化脚本,因为该提供可能会挂起整个自动化流程。
   #找出距此时2天之内创建的文件,同时基于find的结果,应用-exec之后的命令,即ls -l,从而可以直接显示出find找到文件的明显列表。
   /> find . -ctime -2 -exec ls -l {} \;
   -rw-r--r--. 1 root root      279 Nov 11 08:45 ./users2
   -rw-r--r--. 1 root root  48217 Nov 12 00:57 ./install.log
   -rw-r--r--. 1 root root        37 Nov 12 00:56 ./testfile.dat
   -rw-r--r--. 1 root root      183 Nov 11 08:02 ./users
   -rw-r--r--. 1 root root  10530 Nov 11 23:08 ./test.tar.bz2
   #找到文件名为*.log, 同时文件数据修改时间距此时为1天之内的文件。如果找到就删除他们。有的时候,这样的写法由于是在找到之后立刻删除,因此存在一定误删除的危险。
   /> ls
   install.log  testfile.dat  test.tar.bz2  users  users2
   /> find . -name "*.log" -mtime -1 -exec rm -f {} \;
   /> ls
   testfile.dat  test.tar.bz2  users  users2
   在控制台下,为了使上面的命令更加安全,我们可以使用-ok替换-exec,见如下示例:
   />  find . -name "*.dat" -mtime -1 -ok rm -f {} \;
   < rm ... ./testfile.dat > ? y    #对于该提示,如果回答y,找到的*.dat文件将被删除,这一点从下面的ls命令的结果可以看出。
   /> ls
   test.tar.bz2  users  users2

   4. 按文件所属的owner和group查找:
   -user:      查找owner属于-user选项后面指定用户的文件。
   ! -user:    查找owner不属于-user选项后面指定用户的文件。
   -group:   查找group属于-group选项后面指定组的文件。
   ! -group: 查找group不属于-group选项后面指定组的文件。

   5. 按指定目录深度查找:
   -maxdepth: 后面的参数表示距当前目录指定的深度,其中1表示当前目录,2表示一级子目录,以此类推。在指定该选项后,find只是在找到指定深度后就不在递归其子目录了。下例中的深度为1,表示只是在当前子目录中搜索。如果没有设置该选项,find将递归当前目录下的所有子目录。

   6. 排除指定子目录查找:
   -path pathname -prune:   避开指定子目录pathname查找。
   -path expression -prune:  避开表达中指定的一组pathname查找。
   需要说明的是,如果同时使用-depth选项,那么-prune将被find命令忽略。
   #为后面的示例创建需要避开的和不需要避开的子目录,并在这些子目录内均创建符合查找规则的文件。
   /> mkdir DontSearchPath  
   /> cd DontSearchPath
   /> touch datafile1
   /> cd ..
   /> mkdir DoSearchPath
   /> cd DoSearchPath
   /> touch datafile2
   /> cd ..
   /> touch datafile3
   #当前目录下,避开DontSearchPath子目录,搜索所有文件名为datafile*的文件。
   /> find . -path "./DontSearchPath" -prune -o -name "datafile*" -print
   ./DoSearchPath/datafile2
   ./datafile3
   #当前目录下,同时避开DontSearchPath和DoSearchPath两个子目录,搜索所有文件名为datafile*的文件。
   /> find . \( -path "./DontSearchPath" -o -path "./DoSearchPath" \) -prune -o -name "datafile*" -print
   ./datafile3

   7. 按文件权限属性查找:
   -perm mode:   文件权限正好符合mode(mode为文件权限的八进制表示)。
   -perm +mode: 文件权限部分符合mode。如命令参数为644(-rw-r--r--),那么只要文件权限属性中有任何权限和644重叠,这样的文件均可以被选出。
   -perm -mode:  文件权限完全符合mode。如命令参数为644(-rw-r--r--),当644中指定的权限已经被当前文件完全拥有,同时该文件还拥有额外的权限属性,这样的文件可被选出。
   /> ls -l
   -rw-r--r--. 1 root            root           0 Nov 12 10:02 datafile3
   -rw-r--r--. 1 root            root    10530 Nov 11 23:08 test.tar.bz2
   -rw-r--r--. 1 stephen stephen        183 Nov 11 08:02 users
   -rw-r--r--. 1 root            root        279 Nov 11 08:45 users2
   /> find . -perm 644      #查找所有文件权限正好为644(-rw-r--r--)的文件。
   ./users2
   ./datafile3
   ./users
   ./test.tar.bz2
   /> find . -perm 444      #当前目录下没有文件的权限属于等于444(均为644)。    
   /> find . -perm -444     #644所包含的权限完全覆盖444所表示的权限。
   .
   ./users2
   ./datafile3
   ./users
   ./test.tar.bz2
   /> find . -perm +111    #查找所有可执行的文件,该命令没有找到任何文件。
   /> chmod u+x users     #改变users文件的权限,添加owner的可执行权限,以便于下面的命令可以将其找出。
   /> find . -perm +111    
   .
   ./users    

   8. 按文件类型查找:
   -type:后面指定文件的类型。
   b - 块设备文件。
   d - 目录。
   c - 字符设备文件。
   p - 管道文件。
   l  - 符号链接文件。
   f  - 普通文件。
  /> find . ! -type d    #在当前目录下,找出文件类型不为目录的文件。
   9. 按文件大小查找:
   -size [+/-]100[c/k/M/G]: 表示文件的长度为等于[大于/小于]100块[字节/k/M/G]的文件。
   -empty: 查找空文件。
   /> find . -size +4k -exec ls -l {} \;  #查找文件大小大于4k的文件,同时打印出找到文件的明细
   -rw-r--r--. 1 root root 10530 Nov 11 23:08 ./test.tar.bz2
   /> find . -size -4k -exec ls -l {} \;  #查找文件大小小于4k的文件。
   -rw-r--r--. 1 root            root 279 Nov 11 08:45 ./users2
   -rw-r--r--. 1 root             root    0 Nov 12 10:02 ./datafile3
   -rwxr--r--. 1 stephen stephen 183 Nov 11 08:02 ./users
   /> find . -size 183c -exec ls -l {} \; #查找文件大小等于183字节的文件。
   -rwxr--r--. 1 stephen stephen 183 Nov 11 08:02 ./users
   /> find . -empty  -type f -exec ls -l {} \;
   -rw-r--r--. 1 root root 0 Nov 12 10:02 ./datafile3

   10. 按更改时间比指定文件新或比文件旧的方式查找:
   -newer file1 ! file2: 查找文件的更改日期比file1新,但是比file2老的文件。
   /> ls -lrt   #以时间顺序(从早到晚)列出当前目录下所有文件的明细列表,以供后面的例子参考。
   -rwxr--r--. 1 stephen stephen   183 Nov 11 08:02 users1
   -rw-r--r--. 1 root           root    279 Nov 11 08:45 users2
   -rw-r--r--. 1 root           root 10530 Nov 11 23:08 test.tar.bz2
   -rw-r--r--. 1 root           root        0 Nov 12 10:02 datafile3
   /> find . -newer users1     #查找文件更改日期比users1新的文件,从上面结果可以看出,其余文件均符合要求。
   ./users2
   ./datafile3
   ./test.tar.bz2
   /> find . ! -newer users2   #查找文件更改日期不比users1新的文件。
   ./users2
   ./users
   #查找文件更改日期比users2新,但是不比test.tar.bz2新的文件。
   /> find . -newer users2 ! -newer test.tar.bz2
   ./test.tar.bz2  


xargs

在使用find命令的-exec选项处理匹配到的文件时,find命令将所有匹配到的文件一起传递给exec执行。不幸的是,有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现溢出错误。错误信息通常是“参数列太长”或“参数列溢出”。这就是xargs命令的用处所在,特别是与find命令一起使用。Find命令把匹配到的文件传递给xargs命令,而xargs命令每次只获取一部分文件而不是全部,不像-exec选项那样。这样它可以先处理最先获取的一部分文件,然后是下一批,并如此继续下去。

在有些系统中,使用-exec选项会为处理每一个匹配到的文件而发起一个相应的进程,并非将匹配到的文件全部作为参数一次执行;这样在有些情况下就会出现进程过多,系统性能下降的问题,因而效率不高;而使用xargs命令则只有一个进程。另外,在使用xargs命令时,究竟是一次获取所有的参数,还是分批取得参数,以及每一次获取参数的数目都会根据该命令的选项及系统内核中相应的可调参数来确定。

1、多行变成单行
-bash-3.2# cat test.txt
a b c d e f
g o p q
-bash-3.2# cat test.txt |xargs
a b c d e f g o p q
2、单行变成多行
-bash-3.2# cat test.txt
a b c d e f g o p q
-bash-3.2# cat test.txt |xargs -n 2
a b
c d
e f
g o
p q
3、删除某个重复的字符来做定界符
-bash-3.2# cat test.txt
aaaagttttgyyyygcccc
-bash-3.2# cat test.txt |xargs -d g
aaaa tttt yyyy cccc
4、删除某个重复的字符来做定界符后,变成多行
-bash-3.2# cat test.txt |xargs -d g -n 2
aaaa tttt
yyyy cccc
5、用find找出文件以txt后缀,并使用xargs将这些文件删除
-bash-3.2# find /root/ -name "*.txt" -print0 |xargs -0 rm -rf   #查找并删除
-bash-3.2# find /root/ -name "*.txt" -print          #再次查找没有
6、查找普通文件中包括thxy这个单词的
-bash-3.2# find /root/ -type f -print |xargs grep "thxy"
/root/1.doc:thxy
7、查找权限为644的文件,并使用xargs给所有加上x权限
-bash-3.2# find /root/ -perm 644 -print|xargs chmod a+x
-bash-3.2# find /root/ -perm 755 -print