linux 命令詳解 十五

 十六. 文件查找命令find:


   
下面給出find命令的主要應用示例:
    
/> ls -l     #列出當前目錄下所包含的測試文件
    -rw-r--r--. 1 root root 48217 Nov 12 00:57 install.log
    -rw-r--r--. 1 root root      37 Nov 12 00:56 testfile.dat
    -rw-r--r--. 1 root root 10530 Nov 11 23:08 test.tar.bz2
    -rw-r--r--. 1 root root     183 Nov 11 08:02 users
    -rw-r--r--. 1 root root     279 Nov 11 08:45 users2
    
    1. 按文件名查找
    -name:  查找時文件名大小寫敏感。
    -iname: 查找時文件名大小寫不敏感。
    #
該命令爲find命令中最爲常用的命令,即從當前目錄中查找擴展名爲.log的文件。需要說明的是,缺省情況下,find會從指定的目錄搜索,並遞歸的搜索其子目錄。
  
  /> find . -name "*.log"
     ./install.log
   
 /> find . -iname U*          #如果執行find . -name U*將不會找到匹配的文件
    users users2


    2. 按文件時間屬性查找:
    -atime  -n[+n]: 找出文件訪問時間在n日之內[之外]的文件。
    -ctime  -n[+n]: 找出文件更改時間在n日之內[之外]的文件。
    -mtime -n[+n]: 找出修改數據時間在n日之內[之外]的文件。
    -amin   -n[+n]: 找出文件訪問時間在n分鐘之內[之外]的文件。
    -cmin   -n[+n]: 找出文件更改時間在n分鐘之內[之外]的文件。
    -mmin  -n[+n]: 找出修改數據時間在n分鐘之內[之外]的文件。
   
 /> find -ctime -2        #找出距此時2天之內創建的文件
    .
    ./users2
    ./install.log
    ./testfile.dat
    ./users
    ./test.tar.bz2
 
   /> find -ctime +2        #找出距此時2天之前創建的文件
    沒有找到                     #因爲當前目錄下所有文件都是2天之內創建的
   
 /> touch install.log     #手工更新install.log的最後訪問時間,以便下面的find命令可以找出該文件
    
/> find . -cmin  -3       #找出修改狀態時間在3分鐘之內的文件。
    install.log

    
3. 基於找到的文件執行指定的操作:
    -exec: 對匹配的文件執行該參數所給出的shell命令。相應命令的形式爲'command' {} \;,注意{}\;之間的空格,同時兩個{}之間沒有空格
    -ok:   其主要功能和語法格式與-exec完全相同,唯一的差別是在於該選項更加安全,因爲它會在每次執行shell命令之前均予以提示,只有在回答爲y的時候,其後的shell命令纔會被繼續執行。需要說明的是,該選項不適用於自動化腳本,因爲該提供可能會掛起整個自動化流程。
    #
找出距此時2天之內創建的文件,同時基於find的結果,應用-exec之後的命令,即ls -l,從而可以直接顯示出find找到文件的明顯列表。
  
  /> find . -ctime -2 -exec ls -l {} \;
    -rw-r--r--. 1 root root      279 Nov 11 08:45 ./users2
    -rw-r--r--. 1 root root  48217 Nov 12 00:57 ./install.log
    -rw-r--r--. 1 root root        37 Nov 12 00:56 ./testfile.dat
    -rw-r--r--. 1 root root      183 Nov 11 08:02 ./users
    -rw-r--r--. 1 root root  10530 Nov 11 23:08 ./test.tar.bz2
    #
找到文件名爲*.log, 同時文件數據修改時間距此時爲1天之內的文件。如果找到就刪除他們。有的時候,這樣的寫法由於是在找到之後立刻刪除,因此存在一定誤刪除的危險。
   
 /> ls
    install.log  testfile.dat  test.tar.bz2  users  users2
   
 /> find . -name "*.log" -mtime -1 -exec rm -f {} \; 
    /> ls
    testfile.dat  test.tar.bz2  users  users2
   
 在控制檯下,爲了使上面的命令更加安全,我們可以使用-ok替換-exec,見如下示例:
  
  />  find . -name "*.dat" -mtime -1 -ok rm -f {} \;
    
< rm ... ./testfile.dat > ? y    #對於該提示,如果回答y,找到的*.dat文件將被刪除,這一點從下面的ls命令的結果可以看出。
  
  /> ls
    test.tar.bz2  users  users2

 
   4. 按文件所屬的ownergroup查找:
    -user:      查找owner屬於-user選項後面指定用戶的文件。
    ! -user:    查找owner不屬於-user選項後面指定用戶的文件。
    -group:   查找group屬於-group選項後面指定組的文件。
    ! -group: 查找group不屬於-group選項後面指定組的文件。
   
 /> ls -l                            #下面三個文件的owner均爲root
    -rw-r--r--. 1
 root root 10530 Nov 11 23:08 test.tar.bz2
    -rw-r--r--. 1
 root root     183 Nov 11 08:02 users
    -rw-r--r--. 1
 root root     279 Nov 11 08:45 users2
    
/> chown stephen users   #users文件的ownerroot改爲stephen
  
  /> ls -l
    -rw-r--r--. 1
 root       root 10530 Nov 11 23:08 test.tar.bz2
    -rw-r--r--. 1
 stephen root    183 Nov 11 08:02 users
    -rw-r--r--. 1
 root       root     279 Nov 11 08:45 users2
    
/> find . -user root          #搜索ownerroot的文件
    .
    ./users2
    ./test.tar.bz2
    
/> find . ! -user root        #搜索owner不是root的文件,注意!-user之間要有空格
    ./users
  
  /> ls -l                            #下面三個文件的所屬組均爲root
    -rw-r--r--. 1 root     
 root 10530 Nov 11 23:08 test.tar.bz2
    -rw-r--r--. 1 stephen
 root    183 Nov 11 08:02 users
    -rw-r--r--. 1 root      
root    279 Nov 11 08:45 users2
    
/> chgrp stephen users    #users文件的所屬組從root改爲stephen
  
  /> ls -l
    -rw-r--r--. 1 root          
 root    10530 Nov 11 23:08 test.tar.bz2
    -rw-r--r--. 1 stephen
 stephen      183 Nov 11 08:02 users
    -rw-r--r--. 1 root           
 root       279 Nov 11 08:45 users2
    
/> find . -group root        #搜索所屬組是root的文件
    .
    ./users2
    ./test.tar.bz2
    
/> find . ! -group root      #搜索所屬組不是root的文件,注意!-user之間要有空格。    
    ./users

    5. 按指定目錄深度查找:
    -maxdepth: 後面的參數表示距當前目錄指定的深度,其中1表示當前目錄,2表示一級子目錄,以此類推。在指定該選項後,find只是在找到指定深度後就不在遞歸其子目錄了。下例中的深度爲1,表示只是在當前子目錄中搜索。如果沒有設置該選項,find將遞歸當前目錄下的所有子目錄。
    
/> mkdir subdir               #創建一個子目錄,並在該子目錄內創建一個文件
  
  /> cd subdir
    /> touch testfile
    /> cd ..
    #maxdepth
後面的參數表示距當前目錄指定的深度,其中1表示當前目錄,2表示一級子目錄,以此類推。在指定該選項後,find只是在找到指定深度後就不在遞歸其子目錄了。下例中的深度爲1,表示只是在當前子目錄中搜索。如果沒有設置該選項,find將遞歸當前目錄下的所有子目錄。
    /> find . -maxdepth 1 -name "*"
    .
    ./users2
    ./subdir
    ./users
    ./test.tar.bz2
    #
搜索深度爲子一級子目錄,這裏可以看出子目錄下剛剛創建的testfile已經被找到
    /> find . -maxdepth 2 -name "*"  
    .
    ./users2
    ./subdir
    ./subdir/testfile
    ./users
    ./test.tar.bz2
   
 
    6. 排除指定子目錄查找:
    
-path pathname -prune:   避開指定子目錄pathname查找。
    -path expression -prune:  避開表達中指定的一組pathname查找。
    需要說明的是,如果同時使用-depth選項,那麼-prune將被find命令忽略。
    #
爲後面的示例創建需要避開的和不需要避開的子目錄,並在這些子目錄內均創建符合查找規則的文件。
    /> mkdir DontSearchPath  

    /> cd DontSearchPath
    /> touch datafile1
    /> cd ..
    /> mkdir DoSearchPath
    /> cd DoSearchPath
    /> touch datafile2
    /> cd ..
    /> touch datafile3
    #
當前目錄下,避開DontSearchPath子目錄,搜索所有文件名爲datafile*的文件。
    /> find . -path "./DontSearchPath" -prune -o -name "datafile*" -print
    ./DoSearchPath/datafile2
    ./datafile3
    #
當前目錄下,同時避開DontSearchPathDoSearchPath兩個子目錄,搜索所有文件名爲datafile*的文件。
    /> find . \( -path "./DontSearchPath" -o -path "./DoSearchPath" \) -prune -o -name "datafile*" -print
    ./datafile3
       
 
 
   7. 按文件權限屬性查找:
    -perm mode:   文件權限正好符合mode(mode爲文件權限的八進制表示)
    -perm +mode: 文件權限部分符合mode。如命令參數爲644(-rw-r--r--),那麼只要文件權限屬性中有任何權限和644重疊,這樣的文件均可以被選出。
    
-perm -mode:  文件權限完全符合mode。如命令參數爲644(-rw-r--r--),當644中指定的權限已經被當前文件完全擁有,同時該文件還擁有額外的權限屬性,這樣的文件可被選出。
    
/> ls -l
    -rw-r--r--. 1 root            root           0 Nov 12 10:02 datafile3
    -rw-r--r--. 1 root            root    10530 Nov 11 23:08 test.tar.bz2
    -rw-r--r--. 1 stephen stephen        183 Nov 11 08:02 users
    -rw-r--r--. 1 root            root        279 Nov 11 08:45 users2
    
/> find . -perm 644      #查找所有文件權限正好爲644(-rw-r--r--)的文件。
    ./users2
    ./datafile3
    ./users
    ./test.tar.bz2
    
/> find . -perm 444      #當前目錄下沒有文件的權限屬於等於444(均爲644)    
    
/> find . -perm -444     #644所包含的權限完全覆蓋444所表示的權限。
    .
    ./users2
    ./datafile3
    ./users
    ./test.tar.bz2
    
/> find . -perm +111    #查找所有可執行的文件,該命令沒有找到任何文件。
  
  /> chmod u+x users     #改變users文件的權限,添加owner的可執行權限,以便於下面的命令可以將其找出。
    
/> find . -perm +111     
    .
    ./users    
   
 
    8. 按文件類型查找:
    -type後面指定文件的類型。
    b - 塊設備文件。
    d - 目錄。
    c - 字符設備文件。
    p - 管道文件。
    l  - 符號鏈接文件。
    f  - 普通文件。
   
 /> mkdir subdir 
   
 /> find . -type d      #在當前目錄下,找出文件類型爲目錄的文件。
    ./subdir
  /> find . ! -type d    #在當前目錄下,找出文件類型不爲目錄的文件。
    ./users2
    ./datafile3
    ./users
    ./test.tar.bz2
    
/> find . -type f       #在當前目錄下,找出文件類型爲文件的文件
    ./users2
    ./datafile3
    ./users
    ./test.tar.bz2
   
 
    9. 按文件大小查找:
    -size [+/-]100[c/k/M/G]: 表示文件的長度爲等於[大於/小於]100[字節/k/M/G]的文件。
    -empty: 查找空文件。
   
 /> find . -size +4k -exec ls -l {} \;  #查找文件大小大於4k的文件,同時打印出找到文件的明細
    -rw-r--r--. 1 root root
 10530 Nov 11 23:08 ./test.tar.bz2
   
 /> find . -size -4k -exec ls -l {} \;  #查找文件大小小於4k的文件。
    -rw-r--r--. 1 root            root
 279 Nov 11 08:45 ./users2
    -rw-r--r--. 1 root             root   
 0 Nov 12 10:02 ./datafile3
    -rwxr--r--. 1 stephen stephen
 183 Nov 11 08:02 ./users
    
/> find . -size 183c -exec ls -l {} \; #查找文件大小等於183字節的文件。
    -rwxr--r--. 1 stephen stephen
 183 Nov 11 08:02 ./users
    
/> find . -empty  -type f -exec ls -l {} \;
    -rw-r--r--. 1 root root
 0 Nov 12 10:02 ./datafile3
   
 
    10. 按更改時間比指定文件新或比文件舊的方式查找:
    
-newer file1 ! file2 查找文件的更改日期比file1新,但是比file2老的文件。
  
  /> ls -lrt   #以時間順序(從早到晚)列出當前目錄下所有文件的明細列表,以供後面的例子參考。
    -rwxr--r--. 1 stephen stephen   183
 Nov 11 08:02 users1
    -rw-r--r--. 1 root           root    279
 Nov 11 08:45 users2
    -rw-r--r--. 1 root           root 10530
 Nov 11 23:08 test.tar.bz2
    -rw-r--r--. 1 root           root        0
 Nov 12 10:02 datafile3
  
  /> find . -newer users1     #查找文件更改日期比users1新的文件,從上面結果可以看出,其餘文件均符合要求。
    ./users2
    ./datafile3
    ./test.tar.bz2
    
/> find . ! -newer users2   #查找文件更改日期不比users1新的文件。
    ./users2
    ./users
    #
查找文件更改日期比users2新,但是不比test.tar.bz2新的文件。
    
/> find . -newer users2 ! -newer test.tar.bz2
    ./test.tar.bz2
   
 
    細心的讀者可能發現,關於find的說明,在我之前的Blog中已經給出,這裏之所以拿出一個小節再次講述該命令主要是因爲以下三點原因:
    1. find命令在Linux Shell中扮演着極爲重要的角色;
    2. 爲了保證本系列的完整性;
    3. 之前的Blog是我多年之前留下的總結筆記,多少有些粗糙,這裏給出了更爲詳細的舉例。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章