一. name選項 文件名選項是find命令最常用的選項,要麼單獨使用該選項,要麼和其他選項一起使用。 可以使用某種文件名模式來匹配文件,記住要用引號將文件名模式引起來。 不管當前路徑是什麼,如果想要在自己的根目錄$HOME中查找文件名符合 .log的文件,使用~作為 'pathname'參數,波浪 ...
一. name選項
文件名選項是find命令最常用的選項,要麼單獨使用該選項,要麼和其他選項一起使用。 可以使用某種文件名模式來匹配文件,記住要用引號將文件名模式引起來。 不管當前路徑是什麼,如果想要在自己的根目錄$HOME中查找文件名符合*.log的文件,使用~作為 'pathname'參數,波浪號~代表了你的$HOME目錄。
find ~ -name "*.log"
想要在當前目錄及子目錄中查找所有的‘ *.log‘文件,可以用:
find . -name "*.log"
想要的當前目錄及子目錄中查找文件名以一個大寫字母開頭的文件,可以用:
find . -name "[A-Z]*"
想要在/etc目錄中查找文件名以host開頭的文件,可以用:
find /etc -name "host*"
想要查找$HOME目錄中的文件,可以用:
find ~ -name "*"
要想讓系統高負荷運行,就從根目錄開始查找所有的文件。
find / -name "*"
如果想在當前目錄查找文件名以一個個小寫字母開頭,最後是4到9加上.log結束的文件:
命令:
find . -name "[a-z]*[4-9].log" -print
二. perm選項
按照文件許可權模式用-perm選項,按文件許可權模式來查找文件的話。最好使用十進位的許可權表示法。
如在當前目錄下查找文件許可權位為755的文件,即文件屬主可以讀、寫、執行,其他用戶可以讀、執行的文件,可以用:
find . -perm 755
find -perm,根據文件的許可權來查找文件,有三種形式:
find -perm mode
find -perm -mode
find -perm +mode
那麼這三者之間有什麼區別呢?解釋之前首先得簡單說一下linux中文件許可權位的概念。在linux中文件或目錄有三者許可權r,w,x,代表的含義分別是讀、寫、可執行。而一個文件或目錄的屬性中又包括所屬用戶u、所屬組g、其他o三個部分的屬性,分別表示所屬用戶、所屬組、其他用戶對這個文件所擁有的許可權。看起來大概是這個樣子:
所屬用戶 所屬組 其他
rwx rwx rwx
用戶在其擁有許可權的位上設置1,沒有許可權的位設置0。如果將每個部分的這些許可權位看成二進位數,每個部分可以用3位二進位數表示,最大值為7(2^3-1),表示可讀、可寫、可執行。嚴格的來說,文件許可權除了r、w、x以外還有setuid,setgid許可權,等下再解釋。
好了,有了許可權位的基礎,那麼再來看find -perm mode。mode是三個數字表示的,每個數字最大值是7(原因前面解釋過了)。
find -perm mode , 表示嚴格匹配,也就是你的文件許可權位轉換成對應的十進位數字與mode一模一樣,那麼匹配成功,需要註意的是如果mode給的數字不足3位,那麼前面自動添0(嚴格的說是不足4位,原因就是前面所說的setuid,setgid,稍後解釋)
find -perm -mode , 表示mode中轉換成二進位的1在文件許可權位裡面必須匹配,比如mode=644那麼轉換成二進位為110 100 100,而被查找的文件的許可權位也可以被轉換成一個二進位數,兩者在位上為1的部分必須完全匹配,而0則不管。例如被查找的文件的許可權為轉換成二進位數是111 111 111那麼這個比如被匹配,而假如是100 100 100那麼則不會匹配。所以這個'-'的作用歸結起來就是匹配比mode許可權更充足的文件(找不到什麼詞語來形容了)
find -perm +mode , 與 -mode的區別是+mode只需其中的任意一個1的部分被匹配,-mode是所有1的部分都必須被匹配,同樣+mode也不管0位。
現在來解釋setuid,setgid,setuid許可權是用來使其他用戶可以“越權”執行你的命令,而本質上的實現就是在許可權檢查的時候,在進程的的有效UID裡面保存了這個其他用戶的UID,所以許可權得意驗證通過(在這裡的 http://www.2cto.com/os/201205/130111.html 註釋1裡面很簡單的介紹了一下),這些許可權用一個新的3位二進位數表示,有4,2,1三種值,4表示有setuid許可權,2表示有setgid許可權,1表示有粘著位(t)許可權(粘著位許可權最典型的例子是/tmp,每個用戶可以在裡面創建、更新、刪除自己創建(文件所屬用戶是自己)的文件,而不能更改別人的文件)。
$ ls -l
total 0
-rwxrwxrwx 1 fai root 0 Aug 28 15:15 a
-rwxr-xr-x 1 fai root 0 Aug 28 15:15 b
----rw---- 1 fai root 0 Aug 28 15:15 c
-rw-rw-rw- 1 fai root 0 Aug 28 15:15 d
-r-xr--r-- 1 fai root 0 Aug 28 15:15 e
對於許可權進行十進位轉2進位
a(777):111 111 111
b(755):111 101 101
c(060): 000 110 000
d(666):110 110 110
e(544):101 100 100
$ find . -perm +006
.
./b
./d
./a
./e
mode中的006轉為2進位是:000 000110
根據部分匹配的原則,只要在第3組中的第一或者第二位出現1就可以了,所以看到e文件101只是匹配了第一位的1,但是也列印了。而a文件111的情況更是符合這個說法了。註意:c文件雖然出現了110,但是不是對應的組,這個匹配是在相應位的。
$ find . -perm -006
./d
./a
對於-perm -006,也同樣道理去判斷,只是這裡需要完全匹配,也就是mode的二進位中出現1的地方,目標中也要出現才行
需要在最後一組中的第一和第二位同時出現1才能匹配。
a(777):111 111 111
d(666):110 110 110
三. prune選項(此處引用http://blog.sina.com.cn/s/blog_6ad648f30100tqwy.html)
查找時忽略指定目錄,是要使用-prune選項,但實際上最重要的還是要和path配合。-prune的意義是,當路徑字串匹配了path中指定的目錄時 候,find命令不進入這個目錄查找,所以這個選項使用的關鍵,還是在path選項上的使用,也就是path選項和其他選項的配合使用,才能最後確定最終 結果。而path,實際上是對路徑字串的一個字元匹配,但也並不僅僅只匹配於目錄,文件同樣可以被匹配,譬如存在一個目錄結構。
./01.txt
./02.txt
./03.txt
./aaa
./aaa/04.txt
./aaa/05.txt
find . -path "./aaa" -print 匹配中使用通配符,則會輸出
./aaa
./aaa/04.txt
./aaa/05.txt
而如果是find . -path "./aaa" -print ,嚴格等於./aaa目錄,則只輸出
./aaa
而且*通配符會將路徑中的字元"/"也作為普通字元進行貪婪匹配,所以可以匹配到目錄以下的文件,所以在使用這個選項時候不要誤以為這個只對目錄有效,實際上只是一種路徑字元匹配工具。
1.查找文件時,忽略某個目錄
如果加上-prune,則第一個命令效果是:
find . -path "./aaa*" -prune -print
./aaa
因為加入了-prune,在匹配這個目錄同時禁止進入到這個目錄下搜索,於是也就是我們所需要的不進入某個目錄查找。
但如何配合其他選項來使用-path 以及-prune呢?以-name為例,下麵對於配合使用方法進行一下演示。
我們先來看看純粹的-name和-path配合使用是什麼效果:
find -name "*.txt" -path "./aaa" -print
這個命令也相當於
find -name "*.txt" -a -path "./aaa" -print
但一般的-a都被忽略不寫。這個命令對於上面的目錄結構這個命令執行為空結果。也就是,既要文件名稱匹配".txt",同時又要其路徑字 串匹配"./aaa",而文件名匹配".txt"的結果有:
./01.txt
./02.txt
./03.txt
./aaa/04.txt
./aaa/05.txt
路徑字串匹配 "./aaa"的只有
./aaa
二者取and則為空結果,所以上面的命令輸出為空。
如果對-path選項加上-prune
find -name "*.txt" -path "./aaa" -prune -print
實際上與上面那條命令輸出並無區別,只是禁止進入./aaa下匹配而已,但最終的結果仍然是空。
再來看看很多人會誤用的結構:
find -name "*.txt" -path "./aaa" -prune -o -print
也就是比上一條語句在-print前增加一個-o。但實際上這條命令是將當前目錄以及包含./aaa子目錄下的所有文件都列印出來。實際上
,這個語句先執行-o左側的語句,find -name "*.txt" -path "./aaa" -prune,因為匹配為空,則執行-o右側的語句-print,也就是把不匹配左側的文件名列印出來,既然左側沒有匹配為真的,所以也就是所有的文件都被列印。
這裡要留意的是匹配模式項(比如-name "*.txt", -path ....),關係符( -a, -o, ","),與操作符(-print, -exec,- ok)之間的位置關係,特別是操作符在關係符的不同位置上,對於結果也具有決定的作用。
說明:
find [-path ..] [expression]
在路徑列表的後面的是表達式
-path "test" -prune -o -print 是 -path "test" -a -prune -o -print 的簡寫表達式按順序求值, -a 和 -o 都是短路求值,與 shell 的 && 和 || 類似如果
-path "test" 為真,則求值 -prune , -prune 返回真,與邏輯表達式為真;否則不求值 -prune,與邏輯表達式為假。如果 -path "test" -a -prune 為假,則求值 -print ,-print返回真,或邏輯表達式為真;否則不求值 -print,或邏輯表達式為真。
這個表達式組合特例可以用偽碼寫為:
if -path "test" then
-prune
else
比如一個語句
find -name "*.txt" -print -o -path "./aaa" -prune -print (1)
其實也可以略寫為
find -name "*.txt" -o -path "./aaa" -prune
註意第二個語句-o兩側都沒有-print,輸出結果為:
./01.txt
./02.txt
./03.txt
./aaa
這是因為find開始執行,遇到第一個-print命令,則會考慮輸出,但是輸出的時候,則是將剩餘所有的匹配項一起進行匹配操作,也就是執行的是
find -name "*.txt" -print -o -path "./aaa" -prune (註意-print命令的位置)
這個命令執行中相當於
find -path "./aaa" -prune -o -name "*.txt" -print
也 就是在匹配過程中,對於包含了-print部分的匹配項是最後匹配的,因此先匹配到了./aaa路徑,由於-prune的存在禁止進入這個路徑查找,禁止 進入查找,並不會因為-o選項而被逆轉,所以左側匹配了./aaa後,-o右側則是不匹配./aaa項目剩餘的文件繼續去匹配-name模式,匹配的結果 最後被-print列印出來,這也就是我們所期待的忽略某個指定目錄進行搜索的結果。
但是我們要分析的是命令(1)中的結果,命令(1)在遇到第一個-print命令後並執行了輸出,但是這個find命令中還存在第二個-print命令,所以在輸出
./01.txt
./02.txt
./03.txt
結果後,還是要繼續執行,要執行最後一個-print命令,下麵的執行則相當於執行一個
find -name "*.txt" -o -path "./aaa" -prune -print
-o左側匹配-name "*.txt",-o到右側後則是對不能匹配到-name模式的結果,進行-path匹配,輸出結果為
./aaa
所以(1)命令最終的輸出結果就是
./01.txt
./02.txt
./03.txt
./aaa 。
2. 忽略多個文件夾
-a, -o都常見了,但是實際中還可以存在“,“的使用,例如新建一個aaa1目錄,其下有08.txt等文件,若執行
$ find -name "*.txt"
./01.txt
./02.txt
./03.txt
./aaa/04.txt
./aaa/05.txt
./aaa1/08.txt
./aaa1/09.txt
若忽略aaa和aaa1目錄查找txt文件,則可以寫做
$ find -name "*.txt" -print -o -path "./aaa" -prune , -path "./aaa1" -prune (註意","兩側的空格不可忽略)
./01.txt
./02.txt
./03.txt
這也就是同時忽略幾個目錄的寫法,註意每忽略一個目錄,其後都要跟隨一個-prune,而不能幾個-path公用一個-prune。
其實若沒有-prune的使用,也可以忽略某個目錄下文件的匹配,譬如
$find -path "./aaa*" -o -name "*.txt" -print
./01.txt
./02.txt
./03.txt
同樣可以不匹配到./aaa目錄下的文件,但是這裡實際上是搜索過./aaa目錄下的文件並且進行匹對的,只是因為-print在-o的右側輸出,而./aaa下的文件被匹配是在-o的左側,所以最終的結果是達不到被列印輸出的條件。但效率應當是明顯低於使用-prune選項。
四. user和nouser 選項
1. 在$HOME目錄中查找文件屬主為hc的文件
find ~ -user hc -print
2. 在/etc目錄下查找文件屬主為hc的文件:
命令:
find /etc -user hc -print
3. 為了查找屬主帳戶已經被刪除的文件,可以使用-nouser選項。在/home目錄下查找所有的這類文件
find /home -nouser -print
說明:
這樣就能夠找到那些屬主在/etc/passwd文件中沒有有效帳戶的文件。在使用-nouser選項時,不必給出用戶名; find命令能夠為你完成相應的工作。
五.使用group和nogroup選項:
就像user和nouser選項一樣,針對文件所屬於的用戶組, find命令也具有同樣的選項,為了在/apps目錄下查找屬於gem用戶組的文件,可以用:
find /apps -group gem -print
要查找沒有有效所屬用戶組的所有文件,可以使用nogroup選項。下麵的find命令從文件系統的根目錄處查找這樣的文件:
find / -nogroup -print
六.按照更改時間或訪問時間等查找文件:
如果希望按照更改時間來查找文件,可以使用mtime,atime或ctime選項。如果系統突然沒有可用空間了,很有可能某一個文件的長度在此期間增長迅速,這時就可以用mtime選項來查找這樣的文件。
用減號-來限定更改時間在距今n日以內的文件,而用加號+來限定更改時間在距今n日以前的文件。
希望在系統根目錄下查找更改時間在5日以內的文件,可以用:
find / -mtime -5 -print
為了在/var/adm目錄下查找更改時間在3日以前的文件,可以用:
find /var/adm -mtime +3 -print
七.查找比某個文件新或舊的文件:
如果希望查找更改時間比某個文件新但比另一個文件舊的所有文件,可以使用-newer選項。
它的一般形式為:
newest_file_name ! oldest_file_name
其中,!是邏輯非符號。
1.查找更改時間比文件log1新但比文件log3舊的文件
命令:
find -newer log1 ! -newer log3
2.查找當前目錄下更改時間在比log2文件新的文件
命令:
find . -newer log2 -print
八.使用type選項:
1:在/etc目錄下查找所有的目錄
命令:
find /etc -type d -print
2:在當前目錄下查找除目錄以外的所有類型的文件
命令:
find . ! -type d -print
3:在/etc目錄下查找所有的符號鏈接文件
命令:
find /etc -type l -print
九.使用size選項:
可以按照文件長度來查找文件,這裡所指的文件長度既可以用塊(block)來計量,也可以用位元組來計量。以位元組計量文件長度的表達形式為N c;以塊計量文件長度只用數字表示即可。
在按照文件長度查找文件時,一般使用這種以位元組表示的文件長度,在查看文件系統的大小,因為這時使用塊來計量更容易轉換。
1:在當前目錄下查找文件長度大於1 M位元組的文件
命令:
find . -size +1000000c -print
2:在/home/apache目錄下查找文件長度恰好為100位元組的文件:
命令:
find /home/apache -size 100c -print
3:在當前目錄下查找長度超過10塊的文件(一塊等於512位元組)
命令:
find . -size +10 -print
十.使用depth選項:
在使用find命令時,可能希望先匹配所有的文件,再在子目錄中查找。使用depth選項就可以使find命令這樣做。這樣做的一個原因就是,當在使用find命令向磁帶上備份文件系統時,希望首先備份所有的文件,其次再備份子目錄中的文件。
1:find命令從文件系統的根目錄開始,查找一個名為CON.FILE的文件。
命令:
find / -name "CON.FILE" -depth -print
說明:
它將首先匹配所有的文件然後再進入子目錄中查找
十一.使用mount選項:
在當前的文件系統中查找文件(不進入其他文件系統),可以使用find命令的mount選項。
1:從當前目錄開始查找位於本文件系統中文件名以XC結尾的文件
命令:
find . -name "*.XC" -mount -print