shell基礎二:尋找技巧,find及xargs的使用

來源:互聯網
上載者:User
 

shell基礎二:尋找技巧,find及xargs的使用
使用exec或ok來執行shell命令

 

                  使用find時,只要把想要的操作寫在一個檔案裡,就可以用exec來配合find尋找,很方便的

(在有些作業系統中只允許- 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

論壇裡-exec執行指令碼的的例子
使用find 命令尋找某個時間段的11點到12點的shell

建立一個指令碼judgetime,內容如下:

ls -l $*|awk '{split($8,hour,":");if((hour[1]>23 || hour[1] < 1)&&hour[1]<24)print}'

到要尋找的目錄下,運行
find ./ -name "*" -exec judgetime {} /;

注意時間格式為24小時制。
如果要精確到分鐘:

touch -t 04241112 starttemp  #精確到12分鐘
touch -t 04241220 endtemp  #截止到12點20
find [dir] -newer starttemp -a ! -newer endtemp -exec ls -l {} /;

find命令的例子

尋找目前使用者主目錄下的所有檔案,下面兩種方法都可以使用:

 

                                              

$ find $HOME -print
$ find ~ -print

為了在目前的目錄中檔案屬主具有讀、寫入權限,並且檔案所屬組的使用者和其他使用者具有讀許可權的檔案,可以用:

 

                                              

$ find . -type f -perm 644 -exec ls -l {} /;

為了尋找系統中所有檔案長度為0的普通檔案,並列出它們的完整路徑,可以用:

 

                                              

$ find / -type f -size 0 -exec ls -l {} /;

尋找/var/logs目錄中更改時間在7日以前的普通檔案,並在刪除之前詢問它們:

 

                                              

$ find /var/logs -type f -mtime +7 -ok rm {} /;

為了尋找系統中所有屬於root組的檔案,可以用:

 

                                              

$find . -group root -exec ls -l {} /;
-rw-r--r--    1 root     root          595 10月 31 01:09 ./fie1

下面的find命令將刪除當目錄中訪問時間在7日以來、含有數字尾碼的admin.log檔案。該命令只檢查三位元字,所以相應檔案的尾碼不要超過999。
先建幾個admin.log*的檔案 ,才能使用下面這個命令

 

                                              

$ find . -name "admin.log[0-9][0-9][0-9]" -atime -7  -ok
rm {} /;
< rm ... ./admin.log001 > ? n
< rm ... ./admin.log002 > ? n
< rm ... ./admin.log042 > ? n
< rm ... ./admin.log942 > ? n

為了尋找當前檔案系統中的所有目錄並排序,可以用:

 

                                              

$ find . -type d  |sort

為了尋找系統中所有的r m t磁帶裝置,可以用:

 

                                              

$ find /dev/rmt -print

 

                                              

原書為:
為了尋找當前檔案系統中的所有目錄並排序,可以用:
$ find . -type d  -loacl -mount |sort
已更正為:
$ find . -type d |sort


 

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/
......

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

 

                                              

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

上面這個執行太慢,我改成在目前的目錄下尋找

 

                                              

#find . -name "file*" -print | xargs echo "" > /temp/core.log
# cat /temp/core.log
./file6

在目前的目錄下尋找所有使用者具有讀、寫和執行許可權的檔案,並收回相應的寫入權限:

 

                                              

# 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中的特殊含義。

 

 為了尋找當前檔案系統中的所有目錄並排序,可以用:
[code]$ find . -type d -print -local -mount |sort

# find . -type d  | sort
.
./dir1
./file6
./.kde
./.kde/Autostart
./sam
./.xemacs

# ls -l
總用量 52
-rw-r--r--    1 root     root            0 10月 31 18:06 admin.log001
-rw-r--r--    1 root     root            0 10月 31 18:06 admin.log002
-rw-r--r--    1 root     root            0 10月 31 18:06 admin.log042
-rw-r--r--    1 root     root            0 10月 31 18:07 admin.log942
drwxr-xr-x    2 root     root         4096 10月 31 20:26 dir1
-rw-r--r--    1 sam      adm             0 10月 31 01:07 fiel
drwxrwxr-x    2 sam      adm          4096 10月 31 20:25 file6
-rwxrwxr-x    2 sam      adm             0 10月 31 01:01 http3.conf
-rw-r--r--    1 sam      adm         34890 10月 31 00:57 httpd1.conf
-rwxrwxr-x    2 sam      adm             0 10月 31 01:01 httpd.conf
drwxrwxr-x    2 gem      group        4096 10月 26 19:48 sam
-rw-r--r--    1 root     root         2792 10月 31 20:19 temp

 

f i n d命令配合使用e x e c和x a rg s可以使使用者對所匹配到的檔案執行幾乎所有的命令。

下面是find一些常用參數的例子,有用到的時候查查就行了,像上面前幾個貼子,都用到了其中的的一些參數,也可以用man或查看論壇裡其它貼子有find的命令手冊

1、使用name選項

檔案名稱選項是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

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

 

                                              

$ find . -name "[A-Z]*" -print

想要在/ e t c目錄中尋找檔案名稱以h o s t開頭的檔案,可以用:

 

                                              

$ find /etc -name "host*" -print

想要尋找$ H O M E目錄中的檔案,可以用:

 

                                              

$ find ~ -name "*" -print 或find . -print

要想讓系統高負荷運行,就從根目錄開始尋找所有的檔案。

 

                                              

$ find / -name "*" -print

如果想在目前的目錄尋找檔案名稱以兩個小寫字母開頭,跟著是兩個數字,最後是* . t x t的檔案,下面的命令就能夠返回名為a x 3 7 . t x t的檔案:$

 

                                              

$find . -name "[a-z][a-z][0--9][0--9].txt" -print

2、用perm選項

按照檔案許可權模式用- p e r m選項。

按檔案許可權模式來尋找檔案的話。最好使用八進位的許可權標記法。

如在目前的目錄下尋找檔案許可權位為7 5 5的檔案,即檔案屬主可以讀、寫、執行,其他使用者可以讀、執行的檔案,可以用:

 

                                              

$ find . -perm 755 -print

還有一種表達方法:在八位元字前面要加一個橫杠-,表示都匹配,如-007就相當於777,-006相當於666

 

                                              

# ls -l
-rwxrwxr-x    2 sam      adm             0 10月 31 01:01 http3.conf
-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

# find . -perm 006
# find . -perm -006
./sam
./httpd1.conf
./temp

3、忽略某個目錄

如果在尋找檔案時希望忽略某個目錄,因為你知道那個目錄中沒有你所要尋找的檔案,那麼可以使用- p r u n e選項來指出需要忽略的目錄。在使用- p r u n e選項時要當心,因為如果你同時使用了- d e p t h選項,那麼- p r u n e選項就會被f i n d命令忽略。

如果希望在/ a p p s目錄下尋找檔案,但不希望在/ a p p s / b i n目錄下尋找,可以用:

 

                                              

$ find /apps -path "/apps/bin" -prune -o -print

-perm選項中,我的解析
還有一種表達方法:在八位元字前面要加一個橫杠-,表示都匹配,如-007就相當於777,-006相當於666
 

補一個:使用find尋找檔案的時候怎麼避開某個檔案目錄

比如要在/usr/sam目錄下尋找不在dir1子目錄之內的所有檔案

 

                                              

find /usr/sam -path "/usr/sam/dir1" -prune -o -print  

 

                  find [path ..] [expression] 在路徑列表的後面的是運算式
-path "/usr/sam" -prune -o -print 是 -path "/usr/sam" -a -prune -o -print 的簡寫運算式按順序求值, -a 和 -o 都是短路求值,與 shell 的 && 和 || 類似如果 -path "/usr/sam" 為真,則求值 -prune , -prune 返回真,與邏輯運算式為真;否則不求值 -prune ,與邏輯運算式為假。 如果 -path "/usr/sam" -a -prune 為假,則求值 -print ,-print 返回真,或邏輯運算式為真;否則不求值 -print,或邏輯運算式為真。  

這個運算式組合特例可以用偽碼寫為

 

                                              

if -path "/usr/sam"  then
          -prune
else
          -print

避開多個檔案夾

 

                  find /usr/sam /( -path /usr/sam/dir1 -o -path /usr/sam/file1 /) -prune -o -print

圓括弧表示運算式的結合。
/ 表示引用,即指示 shell 不對後面的字元作特殊解釋,而留給 find 命令去解釋其意義。

尋找某一確定檔案,-name等選項加在-o 之後

 

                                              

#find /usr/sam  /(-path /usr/sam/dir1 -o -path /usr/sam/file1 /) -prune -o -name "temp" -print


 

4、使用user和nouser選項

按檔案屬主尋找檔案,如在$ 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使用者組的檔案,可以用:

 

                                              

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.