天天看點

LINUX和UNIXshell程式設計之find和xargs

目錄

          • 為什麼使用find
          • find指令選項
          • 使用find的name選項
          • 使用find的perm選項
          • 使用find的user、nouser選項
          • 使用find的group和nogroup選項
          • 使用find按照更改時間查找檔案
          • find指令之type選項
          • find 指令之size選項
          • find之depth選項
          • find之mount選項
          • find使用exec或ok來執行shell指令
          • find使用xargs
為什麼使用find

有時可能需要在系統中查找具有某一特征的檔案 (例如檔案權限、檔案屬主、檔案長度、檔案類型等等)。這樣做可能有很多原因。可能出于安全性的考慮,或是一般性的系統管理任務,或許隻是為了找出一個不知儲存在什麼地方的檔案。 F i n d是一個非常有效的工具,它可以周遊目前目錄甚至于整個檔案系統來查找某些檔案或目錄。

find指令選項

-name 按照檔案名查找檔案。

-perm 按照檔案權限來查找檔案。

-prune 使用這一選項可以使find指令不在目前指定的目錄中查找,如果同時使用了 -depth

選項,那麼- prune選項将被find指令忽略。

-user 按照檔案屬主來查找檔案。

-group 按照檔案所屬的組來查找檔案。

-mtime -n +n 按照檔案的更改時間來查找檔案, - n表示檔案更改時間距現在n天以内,+ n

表示檔案更改時間距現在 n天以前。

-nogroup查找無有效所屬組的檔案,即該檔案所屬的組在/etc/groups中不存在。

-nouser查找無有效屬主的檔案,即該檔案的屬主在/etc/passwd中不存在。

-newer file1! file2查找更改時間比檔案file1l新但比檔案file2舊的檔案。

-type查找某一類型的檔案,諸如:

b-塊裝置檔案。

d-目錄。

c-字元裝置檔案。

P-管道檔案。

l-符号連結檔案.

f-普通檔案。

-size n[c]查找檔案長度為n塊的檔案,帶有c時表示檔案長度以位元組計。

-depth在查找檔案時,首先查找目前目錄中的檔案,然後再在其子目錄中查找。

-fstype查找位于某一類型檔案系統中的檔案,這些檔案系統類型通常可以在配置檔案 /etc/fstab中找到,該配置檔案中包含了本系統中有關檔案系統的資訊。

-mount在查找檔案時不跨越檔案系統mount點。

-follow如果find指令遇到符号連結檔案,就跟蹤至連結所指向的檔案。

-cpio對比對的檔案使用cpio指令,将這些檔案備份到錄音帶裝置中。

使用find的name選項

指令格式:

find 檔案路徑 -name "按名稱搜尋的形式"
           

例:

在家目錄下查找所有.txt檔案

$ find /home -name " * .txt "

/home/test.txt
/home/test1.txt
/home/tes3.txt
           

想要在目前目錄及子目錄中查找所有的*.txt檔案,可以用:

$ find . -name   " * .txt" 
           

想要的目前目錄及子目錄中查找檔案名以一個大寫字母開頭的檔案,可以用:

$ find ・-name "[A-Z]* " 
           

想要在/etc目錄中查找檔案名以host開頭的檔案,可以用:

$ find /etc -name "host*"
           
/etc/host.conf
/etc/hosts
/etc/hosts.allow
/etc/hosts.deny
/etc/selinux/targeted/active/modules/100/hostname
/etc/hostname
/etc/avahi/hosts
           

想要查找SHOME目錄中的檔案,可以用:

$ find /home -name " * "

使用find的perm選項

指令形式:

find 檔案路徑 -perm "檔案權限"
           

為了在家目錄下查找檔案權限位為755的檔案,即檔案屬主可以讀、寫、執行,其他使用者可以讀、執行的檔案,可以用:

$ find  /home -perm 755 
           
使用find的user、nouser選項

指令格式:

find 路徑  -user  使用者名
           

如果希望按照檔案屬主查找檔案,可以給出相應的使用者名。例如,在SHOME目錄中查找 檔案屬主為dave的檔案,可以用:

$ find /home -user dave 
           

在/etc目錄下查找檔案屬主為uucp的檔案:

$ find /etc -us er uucp 
           

為了查找屬主帳戶已經被删除的檔案,可以使用-nouser選項。這樣就能夠找到那些屬主 在/etc/passwd檔案中沒有有效帳戶的檔案。在使用-nouser選項時,不必給出使用者名;find指令 能夠為你完成相應的工作。例如,希望在/home目錄下查找所有的這類檔案,可以用:

$ find /home -nouser 
           
使用find的group和nogroup選項

就像user和nouser選項一樣,針對檔案所屬于的使用者組,find指令也具有同樣的選項,為了在/apps目錄下查找屬于accts使用者組的檔案,可以用:

$ find /apps  -group accts 
           

要查找沒有有效所屬使用者組的所有檔案,可以使用nogroup選項。下面的find指令從檔案 系統的根目錄處查找這樣的檔案

$ fine / -nogroup
           
使用find按照更改時間查找檔案

如果希望按照更改時間來查找檔案,可以使用mtime選項。如果系統突然沒有可用空間了, 很有可能某一個檔案的長度在此期間增長迅速,這時就可以用mtime選項來查找這樣的檔案。 用減号-來限定更改時間在距今n日以内的檔案,而用加号+來限定更改時間在距今n日以前的 檔案。

希望在系統根目錄下查找更改時間在5日以内的檔案,可以用:

$ find / -mtime - 5 
           

為了在/var/adm目錄下查找更改時間在3日以前的檔案,可以用:

$ find /var/adm -mtime +3 
           
find指令之type選項

指令格式:

find 檔案路徑 -type 查找的檔案類型
           

在/etc目錄下查找所有檔案類型:

$ find /etc -type d 
           

為了在目前目錄下查找除目錄以外的所有類型的檔案,可以用:

$ find ・  ! -type d 
           

為了在/etc目錄下查找所有的符号連結檔案,可以用:

$ find /etc -type l
           
find 指令之size選項

可以按照檔案長度來查找檔案,這裡所指的檔案長度既可以用塊(block)來計量,也可 以用位元組來計量。以位元組計量檔案長度的表達形式為Nc;以塊計量檔案長度隻用數字表示即 可。

為了在目前目錄下查找檔案長度大于1M位元組的檔案,可以用:

$ find ・-size +1000000c 
           

為了在/home/apache目錄下查找檔案長度恰好為100位元組的檔案,可以用:

$ find /home/apache -size 100c 
           

為了在目前目錄下查找長度超過10塊的檔案(一塊等于512位元組),可以用:

$ find ・-size +10 
           
find之depth選項

在使用find指令時,可能希望先比對所有的檔案,再在子目錄中查找。使用depth選項就 可以使find指令這樣做。這樣做的一個原因就是,當在使用find指令向錄音帶上備份檔案系統時, 希望首先備份所有的檔案,其次再備份子目錄中的檔案。

在下面的例子中,find指令從檔案系統的根目錄開始,查找一個名為CON.FILE的檔案。 它将首先比對所有的檔案然後再進入子目錄中查找。

$ find / -name  "CON・FILE"  -depth 
           
find之mount選項

在目前的檔案系統中查找檔案(不進入其他檔案系統),可以使用find指令的mount選項。 在下面的例子中,我們從目前目錄開始查找位于本檔案系統中檔案名以XC結尾的檔案:

$ find ・ -name  “*.XC" -mount 
           
find使用exec或ok來執行shell指令

指令格式:

find  檔案路徑  find指令選項  想要查找的類型檔案  -exec  執行的指令  {} \;
           

當比對到一些檔案以後,可能希望對其進行某些操作,這時就可以使用-exec選項。一旦 find指令比對到了相應的檔案,就可以用-exec選項中的指令對其進行操作(在有些作業系統 中隻允許-exec選項執行諸如Is或Is -1這樣的指令)。大多數使用者使用這一選項是為了查找舊檔案并删除它們。這裡我強烈地建議你在真正執行rm指令删除檔案之前,最好先用Is指令看一 下,确認它們是所要删除的檔案。

exec選項後面跟随着所要執行的指令,然後是一對兒{}, 一個空格和一個,最後是一個分号。

為了使用exec選項,必須要同時使用print選項。如果驗證一下find指令,會發現該指令隻 輸出從目前路徑起的相對路徑及檔案名。

為了用ls-1指令列出所比對到的檔案,可以把Is-l指令放在find指令的-exec選項中,例如:

$ find ・-type f -exec Is -l {} \;
-rwxr-xr-x10rootwheel  1222Jan4 1993./sbin/C80
-rwxr-xr-x10rootwheel  1222Jan4 1993./sbin/Normal
-rwxr-xr-x10rootwheel  1222Jan4 1993. /sbin/Rewid
           

上面的例子中,find指令比對到了目前目錄下的所有普通檔案,并在-exec選項中使用ls-1 指令将它們列出。

為了在/logs目錄中查找更改時間在5日以前的檔案并删除它們,可以用:

$ find /logs -type f -mtime + 5 -exec rm { } ;

記住,在shell中用任何方式删除檔案之前,應當先檢視相應的檔案,一定要小心!

當使用諸如mv或rm指令時,可以使用-exec選項的安全模式。它将在對每個比對到的檔案 進行操作之前提示你。在下面的例子中,find指令在目前目錄中查找所有檔案名以.LOG結尾、 更改時間在5日以上的檔案,并删除它們,隻不過在删除之前先給出提示。

$ find ・-name 11 * .LOG'* -mtime +5 -ok rm {} \; 
< rm ・・・./nets.LOG > ? y
           

按y鍵删除檔案,按n鍵不删除。

任何形式的指令都可以在 - exec選項中使用。在下面的例子中我們使用 grep指令。find指令

首先比對所有檔案名為“ passwd * ”的檔案,例如 passwd、passwd . old、passwd .bak,然後執

行g r e p指令看看在這些檔案中是否存在一個 r o u n d e r使用者。

$ find /etc -name "npasswd*" -exec grep "rounder"  {} \;
rounder:JL9TtUqk8EHwc:500:500::/home/apps/nets/rounder:/bin/sh
           
find使用xargs

xrags指令與exec指令相似,都是在find比對完檔案後在執行相應的指令。不幸的是,有些系統對能夠傳遞給 exec的指令長度有限制,這樣在find指令運作幾分鐘之後,就會出現溢出錯誤。錯誤資訊通常是“參數列太長”或“參數列溢出”。這就是xargs指令的用處所在,特别是與 find指令一起使用。 Find指令把比對到的檔案傳遞給 xargs指令,而xargs指令每次隻擷取一部分檔案而不是全部,不像 -exec選項那樣。這樣它可以先處理最先擷取的一部分檔案,然後是下一批,并如此繼續下去。

下面的例子在整個系統中查找記憶體資訊轉儲檔案(core dump),然後把結果儲存到 /tmp/core.log 檔案中:

$ find ・-name '* core" -print | xargs echo ""     >/ tmp/ core . log
           

下面的例子在/apps/audit目錄下查找所有使用者具有讀、寫和執行權限的檔案,并收回相應 的寫權限:

$ find /apps/audit -perm -7 -print | xargs chmod o-w
           

在下面的例子中,我們用grep指令在所有的普通檔案中搜尋device這個詞:

$ find / -type f -print | xargs grep "device"
           

在下面的例子中,我們用grep指令在目前目錄下的所有普通檔案中搜尋DBO這個詞:

find ・ -name*\rtype f -print  | xargs grep "DBO "
           

注意,在上面的例子中,\用來取消find指令中的* 在shell中的特殊含義。

繼續閱讀