每天一个linux命令:find
1、命令简介
find(find) 命令用来在指定目录下查找文件。任何位于参数之前的字符串都将被视为欲查找的目录名。如果使用该命令时,不设置任何参数,则find命令将在当前目录下查找子目录与文件。并且将查找到的子目录和文件全部进行显示。
2、用法
3、选项
'-H'表示只跟随命令行中指定的符号连接,
'-L'表示跟随所有的符号连接,
'-P'是默认的选项,表示不跟随符号连接。
-D debugoptions. 打印诊断信息
-Olevel Enables query optimisation. 允许查询优化
EXPRESSIONS:表达式可能由下列成份组成:操作符、选项、测试表达式以及动作:
1、操作符为and、or、!的组合。
! expr True if expr is false.
-not expr Same as ! expr, but not POSIX compliant. expr1 expr2 implied "and"; expr2 is not evaluated if expr1 is false. expr1 -a expr2 Same as expr1 expr2. expr1 -and expr2 Same as expr1 expr2, but not POSIX compliant. expr1 -o expr2 Or; expr2 is not evaluated if expr1 is true.
expr1 -or expr2 Same as expr1 -o expr2, but not POSIX compliant. expr1 , expr2 List; both expr1 and expr2 are always evaluated. The value of expr1 is discarded; the value of the list is the value of expr2.The comma operator can be useful for searching for several different types of thing, but traversing the filesystem hierarchy only once. The -fprintf action can be used to list the various matched items into several different output files.
2、设置项针对这次查找任务,而不是仅仅针对某一个文件,设置项总是返回true;
位置选项 (总是真): -daystart -follow -regextype
普通选项 (总是真,在其它表达式前指定):
-depth --help -maxdepth LEVELS -mindepth LEVELS -mount -noleaf
--version -xdev -ignore_readdir_race -noignore_readdir_race
3、测试项(test)则不同,它针对具体的一个文件进行匹配测试,如-name,-user等,返回true或者false;
测试项
-name -type -ok -newer -perm -atime, -ctime, -depth, -group, -links, -mtime,-nogroup, -nouser, -print, -prune, -size, -user and -xdev -atime, -ctime, -depth, -group, -links, -mtime,-nogroup, -nouser, -perm, -print, -prune, -size,-user and –xdev
测试项说明
-name filename #查找名为filename的文件
-perm #按执行权限来查找
-user username #按文件属主来查找
-group groupname #按组来查找
-mtime -n +n #按文件更改时间来查找文件,-n指n天以内,+n指n天以前
-atime -n +n #按文件访问时间来查GIN: 0px">
-ctime -n +n #按文件创建时间来查找文件,-n指n天以内,+n指n天以前
-nogroup #查无有效属组的文件,即文件的属组在/etc/groups中不存在
-nouser #查无有效属主的文件,即文件的属主在/etc/passwd中不存
-newer f1 !f2 找文件,-n指n天以内,+n指n天以前
-ctime -n +n #按文件创建时间来查找文件,-n指n天以内,+n指n天以前
-nogroup #查无有效属组的文件,即文件的属组在/etc/groups中不存在
-nouser #查无有效属主的文件,即文件的属主在/etc/passwd中不存
-newer f1 !f2 #查更改时间比f1新但比f2旧的文件
-type b/d/c/p/l/f #查是块设备、目录、字符设备、管道、符号链接、普通文件
-size n[c] #查长度为n块[或n字节]的文件
-depth #使查找在进入子目录前先行查找完本目录
-fstype #查更改时间比f1新但比f2旧的文件
-type b/d/c/p/l/f #查是块设备、目录、字符设备、管道、符号链接、普通文件
-size n[c] #查长度为n块[或n字节]的文件
-depth #使查找在进入子目录前先行查找完本目录
-fstype #查位于某一类型文件系统中的文件,这些文件系统类型通常可 在/etc/fstab中找到
-mount #查文件时不跨越文件系统mount点
-follow #如果遇到符号链接文件,就跟踪链接所指的文件
-cpio %; #查位于某一类型文件系统中的文件,这些文件系统类型通常可 在/etc/fstab中找到
-mount #查文件时不跨越文件系统mount点
-follow #如果遇到符号链接文件,就跟踪链接所指的文件
-cpio #对匹配的文件使用cpio命令,将他们备份到磁带设备中
-prune #忽略某个目录
4、动作项(action)则是对某一个文件进行某种动作(最常见的如-print)
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 ;
- -print: find命令将匹配的文件输出到标准输出。
- -ls:使用ls -dils 格式将匹配的文件输出到标准输出。
- -exec: find命令对匹配的文件执行该参数所给出的shell命令。
- -ok: 和-exec的作用相同,只不过以一种更为安全的模式来执行该参数所给出的shell命令,在执行每一个命令之前,都会给出提示,让用户来确定是否执行。
4、示例
实例1:-H –L –P指定对符号连接的处理方式
[root@oracledb dir1]# ln -s /bin rootbin [root@oracledb dir1]# find -P . -name pwd [root@oracledb dir1]# find -L . -name pwd ./rootbin/pwd [root@oracledb dir1]# find -H rootbin . -name pwd rootbin/pwd
示例2:根据文件名或者正则表达式进行匹配
列出当前目录及子目录下所有文件和文件夹
[root@zabbix alertscripts]# find . ./sendim.py ./sendmail.py ./sendsms.sh ./sendwechat.py
在当前目录下查找以.py结尾的文件名
[root@zabbix alertscripts]# find . -name "*.py" ./sendim.py ./sendmail.py ./sendwechat.py
在当前目录下查找以.py结尾的文件名 ,但忽略大小写
[root@zabbix alertscripts]# find . -iname "*.PY" ./sendim.py ./sendmail.py ./sendwechat.py
当前目录及子目录下查找所有以.py和.sh结尾的文件
[root@zabbix alertscripts]# find . -name "*.py" -o -name "*.sh" ./sendim.py ./sendmail.py ./sendsms.sh ./sendwechat.py
找出当前目录下不是以.sh结尾的文件
[root@zabbix alertscripts]# find . ! -name "*.sh" . ./sendim.py ./sendmail.py ./sendwechat.py
示例3:匹配文件路径或者文件
find /usr/ -path "*local*"
示例4:基于正则表达式匹配文件路径
[root@zabbix alertscripts]# find . -regex ".*\(\.sh\|\.py\)$" ./sendim.py ./sendmail.py ./sendsms.sh ./sendwechat.py
同上,但忽略大小写
[root@zabbix alertscripts]# find . -iregex ".*\(\.SH\|\.PY\)$" ./sendim.py ./sendmail.py ./sendsms.sh ./sendwechat.py
示例5:搜索但跳出指定的目录
查找当前目录或者子目录下所有文件,但是跳过子目录alertscripts
[root@zabbix zabbix]# find . -path "./alertscripts" -prune -o -name "*.*" . ./web/maintenance.inc.php ./web/zabbix.conf.php ./zabbix_java_gateway.conf ./zabbix_agentd.d ./zabbix_agentd.d/userparameter_mysql.conf ./zabbix_agentd.conf ./alertscripts ./zabbix_java_gateway_logback.xml ./zabbix_server.conf.rpmnew_bak ./zabbix_server.conf_bak ./zabbix_server.conf
示例6:根据文件类型进行搜索
(f 普通文件 l 符号连接 d 目录 c 字符设备 b 块设备 s 套接字 p Fifo )
[root@zabbix alertscripts]# find . -type d .
示例7:基于目录深度搜索 向下最大深度限制为1
[root@zabbix zabbix]# find . -maxdepth 1 . ./web ./zabbix_java_gateway.conf ./zabbix_agentd.d ./zabbix_agentd.conf ./alertscripts ./zabbix_java_gateway_logback.xml ./zabbix_server.conf.rpmnew_bak ./zabbix_server.conf_bak ./zabbix_server.conf
搜索出深度距离当前目录至少2个子目录的所有文件
find . -mindepth 2
示例8:根据文件时间戳进行搜索
find . -type f 时间戳
UNIX/Linux文件系统每个文件都有三种时间戳:
访问时间(-atime/天,-amin/分钟):用户最近一次访问时间。
修改时间(-mtime/天,-mmin/分钟):文件最后一次修改时间。
变化时间(-ctime/天,-cmin/分钟):文件数据元(例如权限等)最后一次修改时间。
搜索最近七天内被访问过的所有文件
find . -type f -atime –7
搜索恰好在七天前被访问过的所有文件
find . -type f -atime 7
搜索超过七天内被访问过的所有文件
find . -type f -atime +7
搜索访问时间超过10分钟的所有文件
find . -type f -amin +10
找出比file.log修改时间更长的所有文件
find . -type f -newer file.log
示例9:根据文件大小进行匹配
搜索大于10KB的文件
find . -type f -size +10k
搜索小于10KB的文件
find . -type f -size –10k
搜索等于10KB的文件
find . -type f -size 10k
示例10:根据文件权限/所有权进行匹配
当前目录下搜索出权限为777的文件
find . -type f -perm 777
找出当前目录下权限不是644的php文件
find . -type f -name "*.php" ! -perm 644
示例11:根据用户/用户组进行匹配
找出当前目录用户zabbix拥有的所有文件
find . -type f -user zabbix
找出当前目录用户组zabbix拥有的所有文件
find . -type f -group zabbix
示例12:–delete 删除匹配文件
删除当前目录下所有.txt文件
find . -type f -name "*.txt" –delete
示例13:列出匹配文件 :
find . -type f -name "*.txt" –ls
5、借助-exec选项与其他命令结合使用
find是我们很常用的一个Linux命令,但是我们一般查找出来的并不仅仅是看看而已,还会有进一步的操作,这个时候exec的作用就显现出来了。exec选项后面跟随着所要执行的命令或脚本,然后是一对儿{ },一个空格和一个\,最后是一个分号。
-exec 参数后面跟的是command命令,它的终止是以;为结束标志的,所以这句命令后面的分号是不可缺少的,考虑到各个系统中分号会有不同的意义,所以前面加反斜杠。{} 花括号代表前面find查找出来的文件名。
找出当前目录下所有root的文件,并把所有权更改为用户oracle
find .-type f -user root -exec chown oracle {} \;
查找当前目录下所有.txt文件并把他们拼接起来写入到all.txt文件中
find . -type f -name "*.txt" -exec cat {} \;> all.txt
将30天前的.log文件移动到old目录中
find . -type f -mtime +30 -name "*.log" -exec cp {} old \;
找出当前目录下所有.txt文件并以“File:文件名”的形式打印出来
find . -type f -name "*.txt" -exec printf "File: %s\n" {} \;
因为单行命令中-exec参数中无法使用多个命令,以下方法可以实现在-exec之后接受多条命令
-exec ./text.sh {} \;
6、find的ok操作
-ok和-exec行为一样,不过它会给出提示,让用户决定是否执行相应的操作。
找出自己家目录下所有的.txt文件并删除
[root@oracledb ~]# find $HOME/. -name "*.txt" -ok rm -f {} \; < rm ... /root/./log1.txt > ? y < rm ... /root/./study/dir2/test.txt > ? y < rm ... /root/./log.txt > ? y [root@oracledb ~]#
7、find与xargs
在使用find命令的-exec选项处理匹配到的文件时, find命令将所有匹配到的文件一起传递给exec执行。但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现溢出错误。错误信息通常是“参数列太长”或“参数列溢出”。这就是xargs命令的用处所在,特别是与find命令一起使用。
find命令把匹配到的文件传递给xargs命令,而xargs命令每次只获取一部分文件而不是全部,不像-exec选项那样。这样它可以先处理最先获取的一部分文件,然后是下一批,并如此继续下去。
在有些系统中,使用-exec选项会为处理每一个匹配到的文件而发起一个相应的进程,并非将匹配到的文件全部作为参数一次执行;这样在有些情况下就会出现进程过多,系统性能下降的问题,因而效率不高;而使用xargs命令则只有一个进程。另外,在使用xargs命令时,究竟是一次获取所有的参数,还是分批取得参数,以及每一次获取参数的数目都会根据该命令的选项及系统内核中相应的可调参数来确定。
来看看xargs命令是如何同find命令一起使用的,并给出一些例子。
查找系统中的每一个普通文件,然后使用xargs命令来测试它们分别属于哪类文件
find . -type f -print | xargs file
在整个系统中查找内存信息转储文件(core dump) ,然后把结果保存到/tmp/core.log 文件中:
find / -name "core" -print | xargs echo "" >/tmp/core.log
用grep命令在所有的普通文件中搜索hostname这个词
find . -type f -print | xargs grep "hostname"
删除3天以前的所有东西
find . -ctime +3 -exec rm -rf {} \;
find ./ -mtime +3 -print|xargs rm -f –r
删除文件大小为零的文件
find ./ -size 0 | xargs rm -f &
find命令配合使用exec和xargs可以使用户对所匹配到的文件执行几乎所有的命令。