Find 指令详解

Find 指令详解
20130116 Chenxin整理
201809 更新
常用示例

根据文件内容查看文件名
find . -type f -exec grep -l 'xyz' {} ;
find . -type f|xargs grep -l 'xyz'

find统计文件大小
find ./* -name "*.rdb.gz" -exec ls -l {} ;| awk 'BEGIN {SUM7=0}{ SUM7+=$5} END {print SUM7}'

find忽略指定格式的文件
find -type f ! -name ".h" -exec rm -rf {} ;
find ./ -type f ! -name "
.h" -exec rm -rf {} ; #删除除.h后缀外 的其他所有文件

find忽略个别目录
如果在查找文件时希望忽略某个目录,因为你知道那个目录中没有你所要查找的文件,那么可以使用-prune选项来指出需要忽略的目录。在使用-prune选项时要当心,因为如果你同时使用了-depth选项,那么-prune选项就会被find命令忽略。如果希望在/apps目录下查找文件,但不希望在/apps/bin目录下查找,可以用:
$ find /apps -path "/apps/bin" -prune -o -print(忽略某个目录)

find查找时间或指定大小的文件
按尺寸查找:
find / -size 1500c (查找1,500字节大小的文件,c表示字节)
find / -size +1500c (查找大于1,500字节大小的文件,+表示大于)
find / -size -1500c (查找小于1,500字节大小的文件,-表示小于)
按时间:
find / -amin n 最后n分钟
find / -atime n 最后n天
find / -cmin n 最后n分钟改变状态
find / -ctime n 最后n天改变状态
查看7天之前的数据:
/usr/bin/find /bak/ -mtime +7 -name ".gz" -exec ls -al {} ;
查看最近1天的数据:
/usr/bin/find /bak/ -mtime -1 -name "
.gz" -exec ls -al {} ;

find报"路径必须在表达式之前"原因
多于一个匹配的情况,dekstop 产生了多个单词,只有第一个会被作为 -name 选项的参数。其余的部分 find 无法识别,于是报错 “路径必须在表达式之前”。所以,如果要在 -name 中使用正则表达式,必须加以转义,防止 shell 首先扩展它。转义的办法就是 '.desktop' 或者 "*desktop",这样 -name 选项总是只接受这一个参数。
find ./ -name ".txt" -exec ls -al {} ;
正则匹配regex
find同时查找多个文件方式-regex,以及对应的操作(批量mv或者ls)
将后缀为.log和.out的mv到restart-log文件夹
find ./ -maxdepth 1 -type f -regex '.
(.log|.out)' -exec mv "{}" "restart-log/{}-date +%Y-%m%d-%H%M%S" ;

以下示例注意-o参数的使用,前后都包含了-mtime.如果含有-exec的时候,在-o的前后也都需要.否则只匹配加了-exec的-o选项.如下
find /data/servers_backup -regex '.(list.tmp|.gz)' -mtime +10
find /data/servers_backup -name "
list.tmp" -mtime +10 -o -name "*.gz" -mtime +10

查找含有htm,并且后面至少有一个字符的文件;以及含有iss字符以及可以含有多个或者是0个u字符的文件名.如下
find ./ -regex '.(htm.|issu).*'
./issue.net
./issue
./index.html

执行方式一 exec说明
命令执行过程,首先find找出文件,然后把文件传到“{}”大括号中,接着执行rm命令。{}代表着该文件(可能是文件名).
-exec必须由一个 ; 结束,而因为通常 shell 都会对 ; 进行处理,所以用 ; 防止这种情况。{} 可能需要写做 '{}',也是为了避免被 shell 过滤.
注: {} 后面必须加上";" 而且"{}"和";"之间必须要有一个空格
find ./ -name ".tar.gz" -exec ls -al {} ;|grep "dump"

批量改名,当前目录下文件
find ./ -maxdepth 1 -type f -name ".out" -exec mv "{}" "tmp/{}-date +%Y-%m%d-%H%M%S" ;
find ./ -maxdepth 1 -type f -name "
.log" -exec mv "{}" "tmp/{}-date +%Y-%m%d-%H%M%S" ;
合二为一(正则)
find ./ -maxdepth 1 -type f -regex '.(.log|.out)' -exec mv "{}" "restart-log/{}-date +%Y-%m%d-%H%M%S" ;
合二为一(使用-o参数)
find ./ -maxdepth 1 -type f -name "
.out" -exec mv "{}" "restart-log/{}-date +%Y-%m%d-%H%M%S" ; -o -name "*.log" -exec mv "{}" "restart-log/{}-date +%Y-%m%d-%H%M%S" ;

查找匹配并批量拷贝:
find ./ -name ".sql.tar.gz" -mtime +30 -exec cp -aprf "{}" /data/old_data_2013 ;
匹配到的文件远程拷贝到远端机器:
find ./ -name "Network_Test_20120
.txt" -exec scp -P 4399 "{}" admin@192.168.0.126:/home/admin/ ;

执行方式二 xargs说明
参考 http://czmmiao.iteye.com/blog/1949225
简介
之所以能用到这个命令,关键是由于很多命令不支持"|"管道来传递参数,而日常工作中有有这个必要,所以就有了xargs命令.例如:
这个命令是错误的 find /sbin -perm +700 |ls -l
这样才是正确的 find /sbin -perm +700 |xargs ls -l

在使用find命令的-exec选项处理匹配到的文件时, find命令将所有匹配到的文件一起传递给exec执行.但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现溢出错误.错误信息通常是"参数列太长"或"参数列溢出".

xargs命令每次只获取一部分文件而不是全部,不像-exec选项那样.有些系统为了避免-exec的劣势,将参数分给多个进程执行.而使用xargs命令则只有一个进程.

find ./ -maxdepth 1 -type f -regex '.*(.log|.out)' |xargs -i mv {} {}date +%Y%m%d-%H%M%S
-i 或者是-I,这得看linux支持了,将xargs的每项名称,一般是一行一行赋值给{},可以用{}代替。
$ ls
1.txt 2.txt 3.txt log.xml
$ ls *.txt |xargs -t -i mv {} {}.bak
mv 1.txt 1.txt.bak
mv 2.txt 2.txt.bak
mv 3.txt 3.txt.bak
$ ls
1.txt.bak 2.txt.bak 3.txt.bak log.xml
注意,-I 必须指定替换字符 -i 是否指定替换字符-可选

find的其他常用参数
1、find命令的一般形式
find pathname -options [-print -exec -ok ...]

2、find命令的参数
pathname 所查找的目录路径.
-print 将匹配的文件输出到标准输出.
-exec 对匹配的文件执行该参数所给出的shell命令.相应命令的形式为'command' {} ;,注意{}和;之间的空格.
-ok 和-exec的作用相同,但以一种更为安全的方式执行命令,在执行每一个命令之前给出提示,让用户来确定是否执行.

3、find命令选项
-name 按照文件名查找文件.后跟"filename".
$ find . -name "[A-Z]" -print
$ find /etc -name "host
" -print
$ find ~ -name "" -print 或find . -print
$ find / -name "
" -print
$ find . -name "[a-z][a-z][0--9][0--9].txt" -print

-perm 按照文件权限来查找文件.
$ find . -perm 755 -print

-prune 使用find查找文件的时候怎么避开某个文件目录.略.

-user 按照文件属主来查找文件.
-nouser 查找无有效属主的文件,即该文件的属主在/etc/passwd中不存在.
-group 按照文件所属的组来查找文件.
-nogroup 查找无有效所属组的文件,即该文件所属的组在/etc/groups中不存在.

-newer file1 ! file2 查找更改时间比文件file1新但比文件file2旧的文件.
如果希望查找更改时间比某个文件新但比另一个文件旧的所有文件,可以使用-newer选项.它的一般形式为:newest_file_name ! oldest_file_name
其中,!是逻辑非符号.

find -newer httpd1.conf ! -newer temp -ls

查找更改时间在比temp文件新的文件:
$ find . -newer temp -print

-type 查找某一类型的文件,诸如:b -块设备文件.d -目录.c -字符设备文件.p -管道文件.l -符号链接文件.f -普通文件.

-size n:[c] 查找文件长度为n块的文件,带有c时表示文件长度以字节计.
在当前目录下查找文件长度大于1 M字节的文件:
find . -size +1000000c
find . -size +1k
find . -size +1M
在/home/apache目录下查找文件长度恰好为100字节的文件:
find /home/apache -size 100c -print
在当前目录下查找长度超过10块的文件(一块等于512字节):
find . -size +10 -print

-maxdepth 2 搜索目录深度为2级.

-fstype 查找位于某一类型文件系统中的文件,这些文件系统类型可以在/etc/fstab中找到,该文件中包含了本系统中有关文件系统的信息.

-follow 如果find命令遇到符号链接文件,就跟踪至链接所指向的文件.

-cpio 对匹配的文件使用cpio命令,将这些文件备份到磁带设备中.
组合使用 find 和 cpio 命令
cd /path/to/source/dir
find . | cpio -pdumv /path/to/destination/dir
cpio命令是一个复制命令,它设计用来将文件复制到或复制出一个 cpio 或 tar 存档文件,并自动地保持文件和子目录的权限、时间和所有权.

-mtime -n +n 按照文件的修改时间来查找文件,
-n表示文件更改时间距现在n天以内,
+n表示文件更改时间距现在n天以前.

find命令还有-atime(访问时间)和-ctime(创建时间)选项,但它们都和-m time选项类似.

-amin n 查找系统中最后N分钟访问的文件
-atime n 查找系统中最后n24小时访问的文件
-cmin n 查找系统中最后N分钟被改变文件状态的文件
-ctime n 查找系统中最后n
24小时被改变文件状态的文件
-mmin n 查找系统中最后N分钟被改变文件数据的文件
-mtime n 查找系统中最后n*24小时被改变文件数据的文件

如果希望按照更改时间来查找文件,可以使用mtime,atime或ctime选项.
如果系统突然没有可用空间了,很有可能某一个文件的长度在此期间增长迅速,这时就可以用mtime选项来查找这样的文件.
用减号-来限定更改时间在距今n日以内的文件,而用加号+来限定更改时间在距今n日以前的文件.
希望在系统根目录下查找更改时间在5日以内的文件,可以用:
$ find / -mtime -5 -print
为了在/var/adm目录下查找更改时间在3日以前的文件,可以用:
$ find /var/adm -mtime +3 -print

posted @ 2020-04-20 15:01  ChanixChen  阅读(887)  评论(0编辑  收藏  举报