話說linux中我最常用的幾個指令就是awk, grep, vim, find,今天我們就來詳細看下find指令的使用
先來一個簡單例子:
Shelloo . 表示查找路徑為目前目錄(你也可以指定為其他工程目錄,譬如:~/workspace/login)
-name 表示搜尋的目標檔名或目錄名(允許使用shell通配符)
通常上述指令已經能夠完成日常工作需求的80%,但是要想完成另外的20%,你必須再深入了解下find指令...
現在假設你需要找Test.java 和TEST.java這兩份文件,這時候你該如何做?
也許你會find . -name "Test.java" 和 find . -name "TEST.java" 執行兩遍
雖然這樣做結果正確,但是有沒有更簡單的方式呢? 答案,自然有
Shell程式碼
find . -name "*.java" # 递归查找当前目录下所有java文件
在不了解find命令之前,也許你需要使用shell for循環來遞歸遍歷目錄,然後對每個找到的study判斷是否為文件(有可能是名為study的目錄),若確實是文件則輸出.說了這麼多,這個方式真的是繁瑣異常,但是如果你了解find指令,那麼just one line!
Shell程式碼
find . -iname "test.java" # -iname 与-name参数含义一样,但是忽略大小写
1.如何指定find搜尋路徑
2.如何指定find搜尋的目標類型(-type)
3.要如何指定find搜尋的檔案名稱或目錄名稱(-name / -iname)
真是不少東西了呢,不過我們要繼續前行,find指令還有很多很有用的參數。
find命令預設是遞歸搜索,它的搜尋演算法應該是我們常說的深度優先遍歷(可以透過指定-depth參數指定採用廣度優先遍歷演算法),但是有時候我們希望僅在當前目錄搜索,或是能夠指定遞迴查找的深度,這時候該如何做呢? 兩個字簡單
-maxdepth: 指定遞歸查找時的目錄最大深度,若為1,表示僅在當前目錄查找
-mindepth: 指定遞歸查找時的目錄最小深度
現在我們看兩個例子(先不要嘗試去運行):
Shell代碼
find ~/scripts -type f -name "study"
在我的機器上執行第一種命令,彈出以下警告:
find: warning: you have specified the -maxdepth option after a non-option argument -name, but options are not positional (-maxdepth affects tests specified before it as well as those specified after tests specified before it as well as those specified after tests). ,你現在你的手上又多了兩把利器-maxdepth 和-mindepth(這個兩個參數,可以提高你的查找效率以及zhuangbility)
find命令還幾個很有用的參數
-mtime: 文件內容最後修改時間
-atime: 檔案最後存取時間
-ctime: 檔案meta資訊最後修改時間(譬如檔案權限)
這幾個參數後面要跟一個整數值使用,eg:
如果你需要查找某個時間段內的修改的文件,這些命令就非常有效了(搞運維的同學應該經常使用)
說了這麼多參數(-name, -iname, -type, -mindepth , -maxdepth, -mtime等等),想必你對find命令已經有所了解,
現在我們來看看find命令的一個好基友----xargs
通常我們需要對查找出來的文件執行某些action,譬如我想查找某個工程目錄下所有使用到StringUtils的java文件,這時候該怎麼辦呢?
方法1我們可以使用eclipse的搜索,方法2我們可以寫腳本,方法3 just one line ...
Shell程式碼
find ~/worksapce/project -name "*.java" | xargs grep "StringUtils"
其中:
find ~/worksapce/project -name "*.java" 将会在家目录下workspace/project中递归查找所有java文件
xargs grep "StringUtils" 表示在文件中(find命令查找出的结果集)查找含有StringUtils字样的文件
也许有人一开始会这样写:find ~/worksapce/project -name "*.java" | grep "StringUtils"
这个命令执行将不会产生任何结果,而原因就是因为没有使用xargs!
现在我们就来说说xargs:xargs是用来把输入流转化为参数的命令(默认把输入流中的空白字符譬如"\n"(换行)替换成" "(空格))
Shell代码
$ cat test a b c d e $ cat test | xargs a b c d e
ind命令将查找出的每一个文件名或目录名默认用"\n"分割,然后通过管道 | 作为输入流传递给grep命令,但是grep命令要求输入流必须是参数的形式,譬如:grep "target" file1 file2 所以必须使用xargs重新将输入流转换为参数
说到这里,一些比较严谨的同学也许会说,这样的命令:find ~/worksapce/project -name "*.java" | grep "StringUtils" 是不严谨,不安全的(这里还谈不上不安全,毕竟只是一个grep命令,但要是变成xargs rm -rf 那就危险了),原因就是find命令默认用"\n"分隔结果列表,而xargs会把"\n"转化成空格,所以当文件路径或者文件名含有"\n"这些字符时,就会被错误替换,这时候你在执行个rm -rf ,哦, 卖糕的...
所以我们应该养成好习惯,这样写
Shell代码
find ~/worksapce/project -name "*.java" -print0 | xargs -0 grep "StringUtils"
print0用'\0'(空字符)分隔结果列表,xargs -0 只会将'\0' 替换成空格,这样就不会出现刚才所说的问题了....
关于find命令,我就说到这里,赶紧尝试吧...
更多Find命令实战相关文章请关注PHP中文网!