Chinaunix首页 | 论坛 | 博客
  • 博客访问: 71066
  • 博文数量: 44
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 0
  • 用 户 组: 普通用户
  • 注册时间: 2016-09-19 16:49
文章分类

全部博文(44)

文章存档

2018年(2)

2017年(1)

2016年(41)

我的朋友

分类: 系统运维

2016-04-29 17:25:40

原文地址:find命令 作者:w787815



  1.  一. 文件查找命令find:

  2. 下面给出find命令的主要应用示例:
  3. ls -l #列出当前目录下所包含的测试文件
  4. -rw-r--r--. 1 root root 48217Nov12 00:57 install.log
  5. -rw-r--r--. 1 root root 37 Nov12 00:56 testfile.dat
  6. -rw-r--r--. 1 root root 10530Nov11 23:08 test.tar.bz2
  7. -rw-r--r--. 1 root root 183Nov11 08:02 users
  8. -rw-r--r--. 1 root root 279Nov11 08:45 users2

  9. 1.1 按文件名查找:
  10. -name: 查找时文件名大小写敏感。
  11. -iname: 查找时文件名大小写不敏感。
  12. #该命令为find命令中最为常用的命令,即从当前目录中查找扩展名为.log的文件。需要说明的是,缺省情况下,find会从指定的目录搜索,并递归的搜索其子目录。
  13. find . -name "*.log"
  14.  ./install.log
  15. find . -iname U* #如果执行find . -name U*将不会找到匹配的文件
  16. users users2


  17. 2. 按文件时间属性查找:
  18. -atime -n[+n]: 找出文件访问时间在n日之内[之外]的文件。
  19. -ctime -n[+n]: 找出文件更改时间在n日之内[之外]的文件。
  20. -mtime -n[+n]: 找出修改数据时间在n日之内[之外]的文件。
  21. -amin -n[+n]: 找出文件访问时间在n分钟之内[之外]的文件。
  22. -cmin -n[+n]: 找出文件更改时间在n分钟之内[之外]的文件。
  23. -mmin -n[+n]: 找出修改数据时间在n分钟之内[之外]的文件。
  24. find -ctime -2 #找出距此时2天之内创建的文件
  25. .
  26. ./users2
  27. ./install.log
  28. ./testfile.dat
  29. ./users
  30. ./test.tar.bz2
  31. find -ctime +2 #找出距此时2天之前创建的文件
  32. 没有找到 #因为当前目录下所有文件都是2天之内创建的
  33. touch install.log #手工更新install.log的最后访问时间,以便下面的find命令可以找出该文件
  34. find . -cmin -3 #找出修改状态时间在3分钟之内的文件。
  35. install.log

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

  57. 4. 按文件所属的owner和group查找:
  58. -user: 查找owner属于-user选项后面指定用户的文件。
  59. ! -user: 查找owner不属于-user选项后面指定用户的文件。
  60. -group: 查找group属于-group选项后面指定组的文件。
  61. ! -group: 查找group不属于-group选项后面指定组的文件。
  62. ls -l #下面三个文件的owner均为root
  63. -rw-r--r--. 1 root root 10530 Nov 11 23:08 test.tar.bz2
  64. -rw-r--r--. 1 root root 183 Nov 11 08:02 users
  65. -rw-r--r--. 1 root root 279 Nov 11 08:45 users2
  66. chown stephen users #将users文件的owner从root改为stephen。
  67. ls -l
  68. -rw-r--r--. 1 root root 10530 Nov 11 23:08 test.tar.bz2
  69. -rw-r--r--. 1 stephen root 183 Nov 11 08:02 users
  70. -rw-r--r--. 1 root root 279 Nov 11 08:45 users2
  71. find . -user root #搜索owner是root的文件
  72. .
  73. ./users2
  74. ./test.tar.bz2
  75. find . ! -user root #搜索owner不是root的文件,注意!和-user之间要有空格。
  76. ./users
  77. ls -l #下面三个文件的所属组均为root
  78. -rw-r--r--. 1 root root 10530 Nov 11 23:08 test.tar.bz2
  79. -rw-r--r--. 1 stephen root 183 Nov 11 08:02 users
  80. -rw-r--r--. 1 root root 279 Nov 11 08:45 users2
  81. chgrp stephen users #将users文件的所属组从root改为stephen
  82. ls -l
  83. -rw-r--r--. 1 root root 10530 Nov 11 23:08 test.tar.bz2
  84. -rw-r--r--. 1 stephen stephen 183 Nov 11 08:02 users
  85. -rw-r--r--. 1 root root 279 Nov 11 08:45 users2
  86. find . -group root #搜索所属组是root的文件
  87. .
  88. ./users2
  89. ./test.tar.bz2
  90. find . ! -group root #搜索所属组不是root的文件,注意!和-user之间要有空格。
  91. ./users

  92. 5. 按指定目录深度查找:
  93. -maxdepth: 后面的参数表示距当前目录指定的深度,其中1表示当前目录,2表示一级子目录,以此类推。在指定该选项后,find只是在找到指定深度后就不在递归其子目录了。下例中的深度为1,表示只是在当前子目录中搜索。如果没有设置该选项,find将递归当前目录下的所有子目录。
  94. mkdir subdir #创建一个子目录,并在该子目录内创建一个文件
  95. cd subdir
  96. touch testfile
  97. cd ..
  98. #maxdepth后面的参数表示距当前目录指定的深度,其中1表示当前目录,2表示一级子目录,以此类推。在指定该选项后,find只是在找到指定深度后就不在递归其子目录了。下例中的深度为1,表示只是在当前子目录中搜索。如果没有设置该选项,find将递归当前目录下的所有子目录。
  99. find . -maxdepth 1 -name "*"
  100. .
  101. ./users2
  102. ./subdir
  103. ./users
  104. ./test.tar.bz2
  105. #搜索深度为子一级子目录,这里可以看出子目录下刚刚创建的testfile已经被找到
  106. find . -maxdepth 2 -name "*"
  107. .
  108. ./users2
  109. ./subdir
  110. ./subdir/testfile
  111. ./users
  112. ./test.tar.bz2

  113. 6. 排除指定子目录查找:
  114. -path pathname -prune: 避开指定子目录pathname查找。
  115. -path expression -prune: 避开表达中指定的一组pathname查找。
  116. 需要说明的是,如果同时使用-depth选项,那么-prune将被find命令忽略。
  117. #为后面的示例创建需要避开的和不需要避开的子目录,并在这些子目录内均创建符合查找规则的文件。
  118. mkdir DontSearchPath
  119. cd DontSearchPath
  120. touch datafile1
  121. cd ..
  122. mkdir DoSearchPath
  123. cd DoSearchPath
  124. touch datafile2
  125. cd ..
  126. touch datafile3
  127. #当前目录下,避开DontSearchPath子目录,搜索所有文件名为datafile*的文件。
  128. find . -path "./DontSearchPath" -prune -o -name "datafile*" -print
  129. ./DoSearchPath/datafile2
  130. ./datafile3
  131. #当前目录下,同时避开DontSearchPath和DoSearchPath两个子目录,搜索所有文件名为datafile*的文件。
  132. find . \( -path "./DontSearchPath" -o -path "./DoSearchPath" \) -prune -o -name "datafile*" -print
  133. ./datafile3
  134.   
  135. 7. 按文件权限属性查找:
  136. -perm mode: 文件权限正好符合mode(mode为文件权限的八进制表示)
  137. -perm +mode: 文件权限部分符合mode。如命令参数为644(-rw-r--r--),那么只要文件权限属性中有任何权限和644重叠,这样的文件均可以被选出。
  138. -perm -mode: 文件权限完全符合mode。如命令参数为644(-rw-r--r--),当644中指定的权限已经被当前文件完全拥有,同时该文件还拥有额外的权限属性,这样的文件可被选出。
  139. ls -l
  140. -rw-r--r--. 1 root root 0 Nov 12 10:02 datafile3
  141. -rw-r--r--. 1 root root 10530 Nov 11 23:08 test.tar.bz2
  142. -rw-r--r--. 1 stephen stephen 183 Nov 11 08:02 users
  143. -rw-r--r--. 1 root root 279 Nov 11 08:45 users2
  144. find . -perm 644 #查找所有文件权限正好为644(-rw-r--r--)的文件。
  145. ./users2
  146. ./datafile3
  147. ./users
  148. ./test.tar.bz2
  149. find . -perm 444 #当前目录下没有文件的权限属于等于444(均为644)
  150. find . -perm -444 #644所包含的权限完全覆盖444所表示的权限。
  151. .
  152. ./users2
  153. ./datafile3
  154. ./users
  155. ./test.tar.bz2
  156. find . -perm +111 #查找所有可执行的文件,该命令没有找到任何文件。
  157. chmod u+x users #改变users文件的权限,添加owner的可执行权限,以便于下面的命令可以将其找出。
  158. find . -perm +111
  159. .
  160. ./users

  161. 8. 按文件类型查找:
  162. -type:后面指定文件的类型。
  163. b - 块设备文件。
  164. d - 目录。
  165. c - 字符设备文件。
  166. p - 管道文件。
  167. l - 符号链接文件。
  168. f - 普通文件。
  169. mkdir subdir
  170. find . -type d #在当前目录下,找出文件类型为目录的文件。
  171. ./subdir
  172.    find . ! -type d #在当前目录下,找出文件类型不为目录的文件。
  173. ./users2
  174. ./datafile3
  175. ./users
  176. ./test.tar.bz2
  177. find . -type f #在当前目录下,找出文件类型为文件的文件
  178. ./users2
  179. ./datafile3
  180. ./users
  181. ./test.tar.bz2

  182. 9. 按文件大小查找:
  183. -size [+/-]100[c/k/M/G]: 表示文件的长度为等于[大于/小于]100块[字节/k/M/G]的文件。
  184. -empty: 查找空文件。
  185. find . -size +4k -exec ls -l {} \; #查找文件大小大于4k的文件,同时打印出找到文件的明细
  186. -rw-r--r--. 1 root root 10530 Nov 11 23:08 ./test.tar.bz2
  187. find . -size -4k -exec ls -l {} \; #查找文件大小小于4k的文件。
  188. -rw-r--r--. 1 root root 279 Nov 11 08:45 ./users2
  189. -rw-r--r--. 1 root root 0 Nov 12 10:02 ./datafile3
  190. -rwxr--r--. 1 stephen stephen 183 Nov 11 08:02 ./users
  191. find . -size 183c -exec ls -l {} \; #查找文件大小等于183字节的文件。
  192. -rwxr--r--. 1 stephen stephen 183 Nov 11 08:02 ./users
  193. find . -empty -type f -exec ls -l {} \;
  194. -rw-r--r--. 1 root root 0 Nov 12 10:02 ./datafile3

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

  212. 细心的读者可能发现,关于find的说明,在我之前的Blog中已经给出,这里之所以拿出一个小节再次讲述该命令主要是因为以下三点原因:
  213. 1. find命令在Linux Shell中扮演着极为重要的角色;
  214. 2. 为了保证本系列的完整性;
  215. 3. 之前的Blog是我多年之前留下的总结笔记,多少有些粗糙,这里给出了更为详细的举例。



  216.  二. xargs命令:

  217. 该命令的主要功能是从输入中构建和执行shell命令。
  218. 在使用find命令的-exec选项处理匹配到的文件时, find命令将所有匹配到的文件一起传递给exec执行。但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现溢出错误。错误信息通常是“参数列太长”或“参数列溢出”。这就是xargs命令的用处所在,特别是与find命令一起使用。
  219. find命令把匹配到的文件传递给xargs命令,而xargs命令每次只获取一部分文件而不是全部,不像-exec选项那样。这样它可以先处理最先获取的一部分文件,然后是下一批,并如此继续下去。
  220. 在有些系统中,使用-exec选项会为处理每一个匹配到的文件而发起一个相应的进程,并非将匹配到的文件全部作为参数一次执行;这样在有些情况下就会出现进程过多,系统性能下降的问题,因而效率不高;
  221. 而使用xargs命令则只有一个进程。另外,在使用xargs命令时,究竟是一次获取所有的参数,还是分批取得参数,以及每一次获取参数的数目都会根据该命令的选项及系统内核中相应的可调参数来确定。
  222. ls -l
  223. -rw-r--r--. 1 root root 0 Nov 12 10:02 datafile3
  224. -rw-r--r--. 1 root root 10530 Nov 11 23:08 test.tar.bz2
  225. -rwxr--r--. 1 root root 183 Nov 11 08:02 users
  226. -rw-r--r--. 1 root root 279 Nov 11 08:45 users2
  227. #查找当前目录下的每一个普通文件,然后使用xargs命令来测试它们分别属于哪类文件。
  228. find . -type f -print | xargs file
  229. ./users2: ASCII text
  230. ./datafile3: empty
  231. ./users: ASCII text
  232. ./test.tar.bz2: bzip2 compressed data, block size = 900k
  233. #回收当前目录下所有普通文件的执行权限。
  234. find . -type f -print | xargs chmod a-x
  235. ls -l
  236. -rw-r--r--. 1 root root 0 Nov 12 10:02 datafile3
  237. -rw-r--r--. 1 root root 10530 Nov 11 23:08 test.tar.bz2
  238. -rw-r--r--. 1 root root 183 Nov 11 08:02 users
  239. -rw-r--r--. 1 root root 279 Nov 11 08:45 users2
  240. #在当面目录下查找所有普通文件,并用grep命令在搜索到的文件中查找hostname这个词
  241. find . -type f -print | xargs grep "hostname"
  242. #在整个系统中查找内存信息转储文件(core dump) ,然后把结果保存到/tmp/core.log 文件中。
  243. find / -name "core" -print | xargs echo "" >/tmp/core.log  

  244. pgrep mysql | xargs kill -9  #直接杀掉mysql的进程
  245. [1]+ Killed mysql

   将/usr/local/test目录下大于100K的文件转移到/tmp目录下

  find /usr/local/test/ -size +100k -exec mv {} /tmp \;

  如果只需要移动文件不移动目录,find /usr/local/test/ -size +100k -type f -exec mv {} /tmp \;


阅读(862) | 评论(0) | 转发(0) |
0

上一篇:shell条件判断式

下一篇:善用判断式

给主人留下些什么吧!~~