Linux文件查找命令find,xargs詳述 1.find 由於f i n d具有強大的功能,所以它的選項也很多,其中大部分選項都值得我們花時間來了解一下。即使系統中含有網路文件系統( N F S ),f i n d命令在該文件系統中同樣有效,只你具有相應的許可權。 在運行一個非常消耗資源的f i n d命令時,很多人都傾向於把它放在後台執行,因為遍歷一個大的文件系統可能會花費很長的時間(這裡是指3 0 G位元組以上的文件系統)。
F i n d命令的一般形式為: find pathname -options [-print -exec -ok ...]
讓我們來看看該命令的參數:
pathname: find命令所查找的目錄路徑。例如用.來表示當前目錄,用/來表示系統根目錄。 -print: find命令將匹配的文件輸出到標準輸出。 -exec: find命令對匹配的文件執行該參數所給出的s h e l l命令。相應命令的形式為' command' {} \;,注意{ }和\;之間的空格。 -ok: 和- e x e c的作用相同,只不過以一種更為安全的模式來執行該參數所給出的s h e l l命令,在執行每一個命令之前,都會給出提示,讓用戶來確定是否執行。
find命令選項 -name:按照文件名查找文件。 -perm:按照文件許可權來查找文件。 -prune:使用這一選項可以使f i n d命令不在當前指定的目錄中查找,如果同時使用-depth選項,那麼-prune將被f i n d命令忽略。 -user: 按照文件屬主來查找文件。 -group:按照文件所屬的組來查找文件。 -mtime -n +n:按照文件的更改時間來查找文件, - n表示文件更改時間距現在n天以內,+ n表示文件更改時間距現在n天以前。F i n d命令還有- a t i m e和- c t i m e選項,但它們都和- m t i m e選項。 -nogroup:查找無有效所屬組的文件,即該文件所屬的組在/ e t c / g r o u p s中不存在。 -nouser:查找無有效屬主的文件,即該文件的屬主在/ e t c / p a s s w d中不存在。 -newer file1 ! file2:查找更改時間比文件f i l e 1新但比文件f i l e 2舊的文件。 -type 查找某一類型的文件,諸如:
b - 塊設備文件。 d - 目錄。 c - 字元設備文件。 p - 管道文件。 l - 符號鏈接文件。 f - 普通文件。
-size n:[c] 查找文件長度為n塊的文件,帶有c時表示文件長度以位元組計。 -depth:在查找文件時,首先查找當前目錄中的文件,然後再在其子目錄中查找。 -fstype:查找位於某一類型文件系統中的文件,這些文件系統類型通常可以在配置文件/ e t c / f s t a b中找到,該配置文件中包含了本系統中有關文件系統的信息。
-mount:在查找文件時不跨越文件系統m o u n t點。 -follow:如果f i n d命令遇到符號鏈接文件,就跟蹤至鏈接所指向的文件。 -cpio:對匹配的文件使用c p i o命令,將這些文件備份到磁帶設備中。
(在有些操作系統中只允許- e x e c選項執行諸如l s或ls -l這樣的命令)。大多數用戶使用這一選項是為了查找舊文件並刪除它們。建議在真正執行r m命令刪除文件之前,最好先用l s命令看一下,確認它們是所要刪除的文件。
e x e c選項後面跟隨著所要執行的命令或腳本,然後是一對兒{ },一個空格和一個\,最後是一個分號。
為了使用e x e c選項,必須要同時使用p r i n t選項。如果驗證一下f i n d命令,會發現該命令只輸出從當前路徑起的相對路徑及文件名。
例如:為了用ls -l命令列出所匹配到的文件,可以把ls -l命令放在f i n d命令的- e x e c選項中 # find . -type f -exec ls -l {} \; -rw-r--r-- 1 root root 34928 2003-02-25 ./conf/httpd.conf -rw-r--r-- 1 root root 12959 2003-02-25 ./conf/magic -rw-r--r-- 1 root root 180 2003-02-25 ./conf.d/README
上面的例子中,f i n d命令匹配到了當前目錄下的所有普通文件,並在- e x e c選項中使用ls -l命令將它們列出。
在/ l o g s目錄中查找更改時間在5日以前的文件並刪除它們: $ find logs -type f -mtime +5 -exec rm {} \;
記住,在s h e l l中用任何方式刪除文件之前,應當先查看相應的文件,一定要小心!當使用諸如m v或r m命令時,可以使用- e x e c選項的安全模式。它將在對每個匹配到的文件進行操作之前提示你。
在下面的例子中, f i n d命令在當前目錄中查找所有文件名以. L O G結尾、更改時間在5日以上的文件,並刪除它們,只不過在刪除之前先給出提示。 $ find . -name "*.conf" -mtime +5 -ok rm {} \; < rm ... ./conf/httpd.conf > ? n
按y鍵刪除文件,按n鍵不刪除。
任何形式的命令都可以在- e x e c選項中使用。
在下面的例子中我們使用g r e p命令。f i n d命令首先匹配所有文件名為" passwd*"的文件,例如passwd、passwd.old、passwd.bak,然後執 行grep命令看看在這些文件中是否存在一個sam用戶。 # find /etc -name "passwd*" -exec grep "sam" {} \; sam:x:501:501::/usr/sam:/bin/bash
2.xargs 在使用f i n d命令的- e x e c選項處理匹配到的文件時, f i n d命令將所有匹配到的文件一起傳遞給e x e c執行。但有些系統對能夠傳遞給e x e c的命令長度有限制,這樣在f i n d命令運行幾分鐘之後,就會出現溢出錯誤。錯誤信息通常是"參數列太長"或"參數列溢出"。這就是x a rg s命令的用處所在,特別是與f i n d命令一起使用。
F i n d命令把匹配到的文件傳遞給x a rg s命令,而x a rg s命令每次只獲取一部分文件而不是全部,不像- e x e c選項那樣。這樣它可以先處理最先獲取的一部分文件,然後是下一批,並如此繼續下去。
在有些系統中,使用- e x e c選項會為處理每一個匹配到的文件而發起一個相應的進程,並非將匹配到的文件全部作為參數一次執行;這樣在有些情況下就會出現進程過多,系統性能下降的問題,因而效率不高; 而使用x a rg s命令則只有一個進程。另外,在使用x a rg s命令時,究竟是一次獲取所有的參數,還是分批取得參數,以及每一次獲取參數的數目都會根據該命令的選項及系統內核中相應的可調參數來確定。
來看看x a rg s命令是如何同f i n d命令一起使用的,並給出一些例子。
下面的例子查找系統中的每一個普通文件,然後使用x a rg s命令來測試它們分別屬於哪類文件 #find . -type f -print | xargs file ./.kde/Autostart/Autorun.desktop: UTF-8 Unicode English text ./.kde/Autostart/.directory: ISO-8859 text\ ......
在當前目錄下查找所有用戶具有讀、寫和執行許可權的文件,並收回相應的寫許可權: # ls -l drwxrwxrwx 2 sam adm 4096 10月 30 20:14 file6 -rwxrwxrwx 2 sam adm 0 10月 31 01:01 http3.conf -rwxrwxrwx 2 sam adm 0 10月 31 01:01 httpd.conf
# find . -perm -7 -print | xargs chmod o-w # ls -l drwxrwxr-x 2 sam adm 4096 10月 30 20:14 file6 -rwxrwxr-x 2 sam adm 0 10月 31 01:01 http3.conf -rwxrwxr-x 2 sam adm 0 10月 31 01:01 httpd.conf
用g r e p命令在所有的普通文件中搜索hostname這個詞: # find . -type f -print | xargs grep "hostname" ./httpd1.conf:# different IP addresses or hostnames and have them handled by the ./httpd1.conf:# VirtualHost: If you want to maintain multiple domains/hostnames on your
用g r e p命令在當前目錄下的所有普通文件中搜索hostnames這個詞: # find . -name \* -type f -print | xargs grep "hostnames" ./httpd1.conf:# different IP addresses or hostnames and have them handled by the ./httpd1.conf:# VirtualHost: If you want to maintain multiple domains/hostnames on your
注意,在上面的例子中, \用來取消f i n d命令中的*在s h e l l中的特殊含義。
3.f i n d命令配合使用e x e c和x a rg s可以使用戶對所匹配到的文件執行幾乎所有的命令。
文件名選項是f i n d命令最常用的選項,要麼單獨使用該選項,要麼和其他選項一起使用。 可以使用某種文件名模式來匹配文件,記住要用引號將文件名模式引起來。 不管當前路徑是什麼,如果想要在自己的根目錄$ H O M E中查找文件名符合* . t x t的文件,使用~作為' p a t h n a m e參數,波浪號~代表了你的$ H O M E目錄。 $ find ~ -name "*.txt" -print
想要在當前目錄及子目錄中查找所有的' * . t x t'文件,可以用: $ find . -name "*.txt" -print
按文件屬主查找文件,如在$ H O M E目錄中查找文件屬主為sam的文件,可以用: $ find ~ -user sam -print
在/ e t c目錄下查找文件屬主為u u c p的文件: $ find /etc -user uucp -print
為了查找屬主帳戶已經被刪除的文件,可以使用- n o u s e r選項。這樣就能夠找到那些屬主在/ e t c / p a s s w d文件中沒有有效帳戶的文件。在使用- n o u s e r選項時,不必給出用戶名; f i n d命令能夠為你完成相應的工作。 例如,希望在/ h o m e目錄下查找所有的這類文件,可以用: $ find /home -nouser -print
5、使用group和nogroup選項
就像u s e r和n o u s e r選項一樣,針對文件所屬於的用戶組, f i n d命令也具有同樣的選項,為了在/ a p p s目錄下查找屬於gem用戶組的文件,可以用: $ find /apps -group gem -print
要查找沒有有效所屬用戶組的所有文件,可以使用n o g r o u p選項。下面的f i n d命令從文件系統的根目錄處查找這樣的文件 $ find / -nogroup-print
6、按照更改時間或訪問時間等查找文件
如果希望按照更改時間來查找文件,可以使用m t i m e,atime或ctime選項。如果系統突然沒有可用空間了,很有可能某一個文件的長度在此期間增長迅速,這時就可以用m t i m e選項來查找這樣的文件。 用減號-來限定更改時間在距今n日以內的文件,而用加號+來限定更改時間在距今n日以前的文件。 希望在系統根目錄下查找更改時間在5日以內的文件,可以用: $ find / -mtime -5 -print
為了在/ v a r / a d m目錄下查找更改時間在3日以前的文件,可以用: $ find /var/adm -mtime +3 -print
7、查找比某個文件新或舊的文件
如果希望查找更改時間比某個文件新但比另一個文件舊的所有文件,可以使用- n e w e r選項。它的一般形式為: newest_file_name ! oldest_file_name
其中,!是邏輯非符號。
查找更改時間比文件sam新但比文件temp舊的文件:
例:有兩個文件 -rw-r--r-- 1 sam adm 0 10月 31 01:07 fiel -rw-rw-rw- 1 sam adm 34890 10月 31 00:57 httpd1.conf -rwxrwxr-x 2 sam adm 0 10月 31 01:01 httpd.conf drw-rw-rw- 2 gem group 4096 10月 26 19:48 sam -rw-rw-rw- 1 root root 2792 10月 31 20:19 temp
在/ e t c目錄下查找所有的目錄,可以用: $ find /etc -type d -print
在當前目錄下查找除目錄以外的所有類型的文件,可以用: $ find . ! -type d -print
在/ e t c目錄下查找所有的符號鏈接文件,可以用: $ find /etc -type l -print
9、使用size選項
可以按照文件長度來查找文件,這裡所指的文件長度既可以用塊( b l o c k)來計量,也可以用位元組來計量。以位元組計量文件長度的表達形式為N c;以塊計量文件長度只用數字錶示即可。 在按照文件長度查找文件時,一般使用這種以位元組表示的文件長度,在查看文件系統的大小,因為這時使用塊來計量更容易轉換。