天天看點

find -exec -ok 的用法 -mtime

http://zhumeng8337797.blog.163.com/blog/static/1007689142011012516171/

-exec:  find指令對比對的檔案執行該參數所給出的s h e l l指令。相應指令的形式為' command' {} \;,注意{ }和\;之間的空格。

-ok:       和- e x e c的作用相同,隻不過以一種更為安全的模式來執行該參數所給出的s h e l l指令,在執行每一個指令之前,都會給出提示,讓使用者來确定是否執行。

使用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選項中

  1. # find . -type f -exec ls -l {} \;
  2. -rw-r--r--    1 root     root        34928 2003-02-25  ./conf/httpd.conf
  3. -rw-r--r--    1 root     root        12959 2003-02-25  ./conf/magic
  4. -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日以上的檔案,并删除它們,隻不過在删除之前先給出提示。

  1. $ find . -name "*.conf"  -mtime +5 -ok rm {} \;
  2. < 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 /home/oracle –mtime 1 –exec cp {} /backup/{}.backup \;即可。

一、find 指令格式

1、find指令的一般形式為;

find pathname -options [-print -exec -ok ...]

2、find指令的參數;

pathname: find指令所查找的目錄路徑。例如用.來表示目前目錄,用/來表示系統根目錄。 -print: find指令将比對的檔案輸出到标準輸出。 -exec: find指令對比對的檔案執行該參數所給出的shell指令。相應指令的形式為'command' {  } \;,注意{   }和\;之間的空格。 -ok: 和-exec的作用相同,隻不過以一種更為安全的模式來執行該參數所給出的shell指令,在執行每一個指令之前,都會給出提示,讓使用者來确定是否執行。

3、find指令選項

-name  按照檔案名查找檔案。 -perm  按照檔案權限來查找檔案。 -prune  使用這一選項可以使find指令不在目前指定的目錄中查找,如果同時使用-depth選項,那麼-prune将被find指令忽略。 -user  按照檔案屬主來查找檔案。 -group  按照檔案所屬的組來查找檔案。 -mtime -n +n  按照檔案的更改時間來查找檔案, - n表示檔案更改時間距現在n天以内,+ n表示檔案更改時間距現在n天以前。find指令還有-atime和-ctime 選項,但它們都和-m time選項。 -nogroup  查找無有效所屬組的檔案,即該檔案所屬的組在/etc/groups中不存在。 -nouser  查找無有效屬主的檔案,即該檔案的屬主在/etc/passwd中不存在。 -newer file1 ! file2  查找更改時間比檔案file1新但比檔案file2舊的檔案。 -type  查找某一類型的檔案,諸如: b - 塊裝置檔案。 d - 目錄。 c - 字元裝置檔案。 p - 管道檔案。 l - 符号連結檔案。 f - 普通檔案。 -size n:[c] 查找檔案長度為n塊的檔案,帶有c時表示檔案長度以位元組計。 -depth:在查找檔案時,首先查找目前目錄中的檔案,然後再在其子目錄中查找。 -fstype:查找位于某一類型檔案系統中的檔案,這些檔案系統類型通常可以在配置檔案/etc/fstab中找到,該配置檔案中包含了本系統中有關檔案系統的資訊。 -mount:在查找檔案時不跨越檔案系統mount點。 -follow:如果find指令遇到符号連結檔案,就跟蹤至連結所指向的檔案。 -cpio:對比對的檔案使用cpio指令,将這些檔案備份到錄音帶裝置中。

另外,下面三個的差別:

   -amin n   查找系統中最後N分鐘通路的檔案   -atime n   查找系統中最後n*24小時通路的檔案   -cmin n   查找系統中最後N分鐘被改變檔案狀态的檔案   -ctime n   查找系統中最後n*24小時被改變檔案狀态的檔案     -mmin n   查找系統中最後N分鐘被改變檔案資料的檔案   -mtime n   查找系統中最後n*24小時被改變檔案資料的檔案

4、使用exec或ok來執行shell指令

使用find時,隻要把想要的操作寫在一個檔案裡,就可以用exec來配合find查找,很友善的 在有些作業系統中隻允許-exec選項執行諸如l s或ls -l這樣的指令。大多數使用者使用這一選項是為了查找舊檔案并删除它們。建議在真正執行rm指令删除檔案之前,最好先用ls指令看一下,确認它們是所要删除的檔案。 exec選項後面跟随着所要執行的指令或腳本,然後是一對兒{ },一個空格和一個\,最後是一個分号。為了使用exec選項,必須要同時使用print選項。如果驗證一下find指令,會發現該指令隻輸出從目前路徑起的相對路徑及檔案名。 例如:為了用ls -l指令列出所比對到的檔案,可以把ls -l指令放在find指令的-exec選項中

# 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

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

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

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

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

$ find . -name "*.conf"  -mtime +5 -ok rm {  } \; < rm ... ./conf/httpd.conf > ? n

按y鍵删除檔案,按n鍵不删除。 任何形式的指令都可以在-exec選項中使用。 在下面的例子中我們使用grep指令。find指令首先比對所有檔案名為“ passwd*”的檔案,例如passwd、passwd.old、passwd.bak,然後執行grep指令看看在這些檔案中是否存在一個sam使用者。

# find /etc -name "passwd*" -exec grep "sam" {  } \; sam:x:501:501::/usr/sam:/bin/bash

二、find指令的例子;

1、查找目前使用者主目錄下的所有檔案:

下面兩種方法都可以使用

$ find $HOME -print $ find ~ -print

2、讓目前目錄中檔案屬主具有讀、寫權限,并且檔案所屬組的使用者和其他使用者具有讀權限的檔案;

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

3、為了查找系統中所有檔案長度為0的普通檔案,并列出它們的完整路徑;

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

4、查找/var/logs目錄中更改時間在7日以前的普通檔案,并在删除之前詢問它們;

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

5、為了查找系統中所有屬于root組的檔案;

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

6、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

7、為了查找目前檔案系統中的所有目錄并排序;

$ find . -type d | sort

8、為了查找系統中所有的rmt錄音帶裝置;

$ find /dev/rmt -print

三、xargs

xargs - build and execute command lines from standard input 在使用find指令的-exec選項處理比對到的檔案時, find指令将所有比對到的檔案一起傳遞給exec執行。但有些系統對能夠傳遞給exec的指令長度有限制,這樣在find指令運作幾分鐘之後,就會出現 溢出錯誤。錯誤資訊通常是“參數列太長”或“參數列溢出”。這就是xargs指令的用處所在,特别是與find指令一起使用。 find指令把比對到的檔案傳遞給xargs指令,而xargs指令每次隻擷取一部分檔案而不是全部,不像-exec選項那樣。這樣它可以先處理最先擷取的一部分檔案,然後是下一批,并如此繼續下去。 在有些系統中,使用-exec選項會為處理每一個比對到的檔案而發起一個相應的程序,并非将比對到的檔案全部作為參數一次執行;這樣在有些情況下就會出現程序過多,系統性能下降的問題,因而效率不高; 而使用xargs指令則隻有一個程序。另外,在使用xargs指令時,究竟是一次擷取所有的參數,還是分批取得參數,以及每一次擷取參數的數目都會根據該指令的選項及系統核心中相應的可調參數來确定。 來看看xargs指令是如何同find指令一起使用的,并給出一些例子。 下面的例子查找系統中的每一個普通檔案,然後使用xargs指令來測試它們分别屬于哪類檔案

#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

用grep指令在所有的普通檔案中搜尋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

用grep指令在目前目錄下的所有普通檔案中搜尋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

注意,在上面的例子中, \用來取消find指令中的*在shell中的特殊含義。 find指令配合使用exec和xargs可以使使用者對所比對到的檔案執行幾乎所有的指令。

四、find 指令的參數

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

1、使用name選項

檔案名選項是find指令最常用的選項,要麼單獨使用該選項,要麼和其他選項一起使用。 可以使用某種檔案名模式來比對檔案,記住要用引号将檔案名模式引起來。 不管目前路徑是什麼,如果想要在自己的根目錄$HOME中查找檔案名符合*.txt的檔案,使用~作為 'pathname'參數,波浪号~代表了你的$HOME目錄。

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

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

$ find . -name "*.txt" -print

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

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

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

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

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

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

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

$ find / -name "*" -print

如果想在目前目錄查找檔案名以兩個小寫字母開頭,跟着是兩個數字,最後是.txt的檔案,下面的指令就能夠傳回名為ax37.txt的檔案:

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

2、用perm選項

按照檔案權限模式用-perm選項,按檔案權限模式來查找檔案的話。最好使用八進制的權限表示法。 如在目前目錄下查找檔案權限位為755的檔案,即檔案屬主可以讀、寫、執行,其他使用者可以讀、執行的檔案,可以用:

$ 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

-perm mode:檔案許可正好符合mode -perm +mode:檔案許可部分符合mode -perm -mode: 檔案許可完全符合mode

3、忽略某個目錄

如果在查找檔案時希望忽略某個目錄,因為你知道那個目錄中沒有你所要查找的檔案,那麼可以使用-prune選項來指出需要忽略的目錄。在使用-prune選項時要當心,因為如果你同時使用了-depth選項,那麼-prune選項就會被find指令忽略。 如果希望在/apps目錄下查找檔案,但不希望在/apps/bin目錄下查找,可以用:

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

4、使用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

5、使用user和nouser選項

按檔案屬主查找檔案,如在$HOME目錄中查找檔案屬主為sam的檔案,可以用:

$ find ~ -user sam -print

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

$ find /etc -user uucp -print

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

$ find /home -nouser -print

6、使用group和nogroup選項

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

$ find /apps -group gem -print

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

$ find / -nogroup-print

7、按照更改時間或通路時間等查找檔案

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

$ find / -mtime -5 -print

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

$ find /var/adm -mtime +3 -print

8、查找比某個檔案新或舊的檔案

如果希望查找更改時間比某個檔案新但比另一個檔案舊的所有檔案,可以使用-newer選項。它的一般形式為:

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 # find -newer httpd1.conf  ! -newer temp -ls 1077669    0 -rwxrwxr-x   2 sam      adm             0 10月 31 01:01 ./httpd.conf 1077671    4 -rw-rw-rw-   1 root     root         2792 10月 31 20:19 ./temp 1077673    0 -rw-r--r--   1 sam      adm             0 10月 31 01:07 ./fiel

查找更改時間在比temp檔案新的檔案:

$ find . -newer temp -print

9、使用type選項

在/etc目錄下查找所有的目錄,可以用:

$ find /etc -type d -print

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

$ find . ! -type d -print

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

$ find /etc -type l -print

10、使用size選項

可以按照檔案長度來查找檔案,這裡所指的檔案長度既可以用塊(block)來計量,也可以用位元組來計量。以位元組計量檔案長度的表達形式為N c;以塊計量檔案長度隻用數字表示即可。 在按照檔案長度查找檔案時,一般使用這種以位元組表示的檔案長度,在檢視檔案系統的大小,因為這時使用塊來計量更容易轉換。

在目前目錄下查找檔案長度大于1 M位元組的檔案:

$ find . -size +1000000c -print

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

$ find /home/apache -size 100c -print

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

$ find . -size +10 -print

11、使用depth選項

在使用find指令時,可能希望先比對所有的檔案,再在子目錄中查找。使用depth選項就可以使find指令這樣做。這樣做的一個原因就是,當在使用find指令向錄音帶上備份檔案系統時,希望首先備份所有的檔案,其次再備份子目錄中的檔案。 在下面的例子中, find指令從檔案系統的根目錄開始,查找一個名為CON.FILE的檔案。 它将首先比對所有的檔案然後再進入子目錄中查找。

$ find / -name "CON.FILE" -depth -print

12、使用mount選項

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

$ find . -name "*.XC" -mount -print

find規定了源代碼目錄,并對檔案名檔案類型進行了限定。 

由于我的代碼是在svn管理下的,後面的grep需要将.svn目錄過濾掉。 

然後裡面還用了一些開源項目log4cplus、zlib、gtest,也過濾掉。總之grep進行更加靈活的過濾。 

接下來的xargs作用是把分行的輸出用空格拼接起來,将結果傳遞給wc做輸入。 

wc -l便是統計檔案的行數了。 

例如 

find ./src -type f| grep -v .svn | grep -v log4cplus-1.0.3-rc3 |grep -v zlib-1.2.3 |grep -v gtest |xargs wc -l 

find . -name "*.cc" -or -name "*.h" -or -name "*.sh" | grep -v .svn|xargs wc -l 

find .| grep -v CVS| xargs wc -l

find . -name "*" | xargs -i cp {}  /home/users/

-i 表示 find 傳遞給xargs的結果 由{}來代替 

-I 必須指定替換字元 -i 是否指定替換字元-可選

舉例:

find . | xargs -I {}    cp    {}     $D_PATH

find . | xargs -i cp    {}     $D_PATH

兩者效果相同

{}代表cp這個指令的第一個參數   [linux@/home]# pwd |xargs -i cp /etc/syslog.conf {} 上面這條指令會複制etc目錄下的syslog.conf到目前目錄下 {}這對括号表示的是cp的第二個參數,他的值由前面的pwd指令取得,并由xargs指令傳給cp

在unix或linux環境中經常會用到find -mtime這樣的寫法來找某某時間點之前的檔案,至于如何寫find -mtime +N/-N/N,原來并不是很清楚,今天找了些資料看看,畫下了這個圖,以便了解和記憶:

find -exec -ok 的用法 -mtime

從圖上可以看出,以目前時間點開始算起,+表示往左,從該時間點開始再繼續往更早推,可以稱作xx以外;-表示往右,從該時間點算起往後的時間推,可以稱作xx以内;沒有加減号表示據此此前第N天。是以:

我們來看下面這個例子:

我目前的時間2011年3月1日22:31,我有如下的檔案:

E:\testpath>ls -l

total 0

-rwxrwxrwa   1 Administrator   None                  0 Feb 25 22:37 111.txt

-rwxrwxrwa   1 Administrator   None                  0 Feb 26 22:38 222.txt

-rwxrwxrwa   1 Administrator   None                  0 Feb 27 22:38 333.txt

-rwxrwxrwa   1 Administrator   None                  0 Feb 28 22:01 444.txt

-rwxrwxrwa   1 Administrator   None                  0 Feb 28 22:30 555.txt

-rwxrwxrwa   1 Administrator   None                  0 Mar  1 22:31 666.txt < -- 目前時間的檔案

-rwxrwxrwa     1   Administrator     None                    0   Mar    2    2011   777 . txt

E: \ testpath >

E:\testpath>

-mtime +2,表示2天以外的,即從距離目前時間(2011-03-01 22:31)的2天前開始算起,往更早的時間推移。是以,距離目前時間的2天為:2011-02-27 22:31,在此前的檔案,會被選出來。

E:\testpath>find ./ -mtime +2

./111.txt

./222.txt

-mtime +1,表示1天以外的,即從距目前時間的1天前算起,往更早的時間推移。是以2011-02-28 22:31前的檔案屬于該結果,2011-02-28 22:31後的檔案不屬于該結果:

E:\testpath>find ./ -mtime +1

./111.txt

./222.txt

./333.txt

./444.txt

./555.txt

-mtime 2, 距離目前時間第2天的檔案,目前時間為2011-03-01 22:31,往前推2天為2011-02-27 22:31,是以以此為時間點,24小時之内的時間為2011-02-27 22:31~2011-02-28 22:31,是以這段時間内的檔案會被選中出來:

E:\testpath>find ./ -mtime 2

./333.txt

./444.txt

./555.txt

-mtime 1, 距離目前時間第1天的檔案,目前時間為2011-03-01 22:31,往前推1天為2011-02-28 22:31,是以以此為時間點,24小時之内的時間為2011-02-28 22:31~2011-03-01 22:31,是以這段時間内的檔案會被選中出來:

E:\testpath>find ./ -mtime 1

./666.txt

-mtime -1 表示1天以内的,從距目前時間的1天為2011-02-28 22:31,往右推移:

E:\testpath>find ./ -mtime -1

./

./666.txt

./777.txt

-mtime -2 表示2天以内的,從距目前時間的2天為2011-02-27 22:31開始,往右推移:

E:\testpath>find ./ -mtime -2

./

./333.txt

./444.txt

./555.txt

./666.txt

./777.txt

find [起始目錄] 尋找條件 操作

  還有種表述方式:find PATH OPTION [-exec COMMAND { } \;]

  因為find指令會根據我們給的option,也就是尋找條件從我們給出的目錄開始對其中檔案及其下子目錄中的檔案進行遞歸搜尋,是以我覺的這個地方說是“起始目錄”是非常好的。

  該指令中的尋找條件可以是一個用邏輯運算符 not、and、or 組成的複合條件。邏輯運 算符 and、or、not 的含義為:

   (1) and:邏輯與,在指令中用“-a”表示,是系統預設的選項,表示隻有當所給的條 件都滿足時,尋找條件才算滿足。例如:

  find –name ’tmp’ –xtype c -user ’inin’

  % 該指令尋找三個給定條件都滿足的所有檔案

   (2) or:邏輯或,在指令中用“-o”表示。該運算符表示隻要所給的條件中有一個滿足 時,尋找條件就算滿足。例如:

  find –name ’tmp’ –o –name ’mina*’

  % 該指令查詢檔案名為’tmp’或是比對’mina*’的所有檔案。

   (3) not:邏輯非,在指令中用“!”表示。該運算符表示查找不滿足所給條件的檔案 。例如:

  find ! –name ’tmp’

  % 該指令查詢檔案名不是’tmp’的所有檔案。

  需要說明的是:當使用很多的邏輯選項時,可以用括号把這些選項括起來。為了避免Shell本身對括号引起誤解,在話号前需要加轉義字元“\”來去除括号的意義。例:

  find \(–name ’tmp’ –xtype c -user ’inin’ \)

  我覺的現在我應該說下出了查詢條件,在find中的option的内容了:

  在option中,具體有參數:

  -name ’字串’ 查找檔案名比對所給字串的所有檔案,字串内可用通配符 *、?、[ ]。

  -lname ’字串’ 查找檔案名比對所給字串的所有符号連結檔案,字串内可用通配符 *、?、[ ]。

  -gid n 查找屬于ID号為 n 的使用者組的所有檔案。

  -uid n 查找屬于ID号為 n 的使用者的所有檔案。

  -group ’字串’ 查找屬于使用者組名為所給字串的所有的檔案。

  -user ’字串’ 查找屬于使用者名為所給字串的所有的檔案。

  -empty 查找大小為 0的目錄或檔案。

  -path ’字串’ 查找路徑名比對所給字串的所有檔案,字串内可用通配符*、?、[ ]。

  -perm 權限 查找具有指定權限的檔案和目錄,權限的表示可以如711,644。

  -size n[bckw] 查找指定檔案大小的檔案,n 後面的字元表示機關,預設為 b,代表512位元組的塊。

  -type x 查找類型為 x 的檔案,x 為下列字元之一:

  b 塊裝置檔案

  c 字元裝置檔案

  d 目錄檔案

  p 命名管道(FIFO)

  f 普通檔案

  l 符号連結檔案(symbolic links)

  s socket檔案

  -xtype x 與 -type 基本相同,但隻查找符号連結檔案。

  以時間為條件查找

  -amin n 查找n分鐘以前被通路過的所有檔案。

  -atime n 查找n天以前被通路過的所有檔案。

  -cmin n 查找n分鐘以前檔案狀态被修改過的所有檔案。

  -ctime n 查找n天以前檔案狀态被修改過的所有檔案。

  -mmin n 查找n分鐘以前檔案内容被修改過的所有檔案。

  -mtime n 查找n天以前檔案内容被修改過的所有檔案。

  -print:将搜尋結果輸出到标準輸出。

  例子:在root以及子目錄查找不包括目錄/root/bin的,greek使用者的,檔案類型為普通檔案的,3天之前的名為test-find.c的檔案,并将結構輸出,find指令如下:

  find / -name "test-find.c" -type f -mtime +3 -user greek -prune /root/bin -print

  當然在這其中,-print是一個預設選項,我們不必刻意去配置它。

  我們再看一下exec選項:

  -exec:對搜尋的結構指令指定的shell指令。注意格式要正确:"-exec 指令 {} \;"

  在}和\之間一定要有空格才行;

  {}表示指令的參數即為所找到的檔案;指令的末尾必須以“ \;”結束。

  例子:對上述例子搜尋出來的檔案進行删除操作,指令如下:

  find / -name "test-find.c" -type f -mtime +3 -user greek -prune /root/bin -exec rm {} \;

  find指令指令執行個體:

  find . - name ‘main*’ - exec more {} \;

  % 查找目前目錄中所有以main開頭的檔案,并顯示這些檔案的内容。

  find . \(- name a.out - o - name ‘*.o’\)> - atime +7 - exec rm {} \;

  % 删除目前目錄下所有一周之内沒有被通路過的a .out或*.o檔案。

  % 指令中的“.”表示目前目錄,此時 find 将從目前目錄開始,逐個在其子目錄中查找滿足後面指定條件的檔案。

  % “\(” 和 “\)” 表示括号(),其中的 “\” 稱為轉義符。之是以這樣寫是由于對 Shell 而言,(和)另有不同的含義,而不是這裡的用于組合條件的用途。

  % “-name a.out” 是指要查找名為a.out的檔案;

  % “-name ‘*.o’” 是指要查找所有名字以 .o 結尾的檔案。

  這兩個 -name 之間的 -o 表示邏輯或(or),即查找名字為a.out或名字以 .o結尾的檔案。

  % find指令在目前目錄及其子目錄下找到這佯的檔案之後,再進行判斷,看其最後通路時間 是否在7天以前(條件 -atime +7),若是,則對該檔案執行指令 rm(-exec rm {} \;)。

  其中 {} 代表目前查到的符合條件的檔案名,\;則是文法所要求的。

  % 上述指令中第一行的最後一個 \ 是續行符。當指令太長而在一行寫不下時,可輸入一個 \,之後系統将顯示一個 >,訓示使用者繼續輸入指令。

在 Linux 平台下找檔案不外乎使用威力強大的 find 指令,威力強大的背後就是有一點點學習曲線,不過整體上來說還算簡單,是以想寫一篇文章留下備忘,讓自己日後可以快速查閱參考。

【 基本語法 】

查詢檔案名稱 ( 也可以查詢「目錄名稱」,其中 * 是萬用字元 )

find $HOME -name '*.mp3'      

   註1: $HOME 是 Linux 下的一個環境變數,預設指向執行帳號的 HOME 目錄

查詢檔案名稱 (不區分大小寫)

find /etc -iname 'Network'      

指定隻要搜尋「檔案」名稱

find /var/log -iname '*.log' -type f      

指定隻要搜尋「目錄」名稱

find /etc -iname 'apache2' -type d      

   補充說明:可用的 –type 參數值如下

b      block (buffered) special

c      character (unbuffered) special

d      directory ( 一般目錄 )

p      named pipe (FIFO)

f      regular file ( 一般檔案 )

l      symbolic link

s      socket

D      door (Solaris)

找尋所有檔案大小大於 50MB 的檔案

find /var -type f -size +50M      

   註1: 不加上 –name 參數即代表搜尋所有檔案

找尋所有檔案大小小於 50MB 的檔案

find /var -type f -size -50M      

尋找超過 7 天沒有被存取或修改過的檔案 (判斷檔案存取時間)

find $HOME -type f -atime +7      

尋找曾經在 7 天內被存取或修改過的檔案 (判斷檔案存取時間)

find $HOME -type f -atime -7      

尋找超過 10 分鐘沒有被存取或修改過的檔案 (判斷檔案存取時間)

find $HOME -type f -amin +10      

尋找曾經在 10 分鐘內被存取或修改過的檔案 (判斷檔案存取時間)

find $HOME -type f -amin -10      

尋找檔案建立時間已超過 30 天的檔案

find $HOME -type f -ctime +30      

尋找特定使用者的檔案 ( 以帳號名稱 tom 為例 )

find $HOME -type f -user tom      

【 進階應用 】

刪除 30 天以上未經存取過的暫存檔案 ( 注意: 以下指令最後一個分號(;)前一定要加上反斜線 )

find /tmp -type f -atime +30 -print -exec rm -f '{}' \;      

   註1: 加上 –print 是為了讓被刪除的檔案檔名一併顯示在畫面上,這個參數可以省略 

   註2: 使用 –exec 會讓查詢到的每一個檔案路徑代入 ‘{}’ 位置,一個檔案會執行一遍 rm 指令

刪除 30 天以上未經存取過的暫存檔案 ( 使用 xargs 當成單一指令的參數 )

find /tmp -type f -print0 | xargs -0 rm -v      

   註1: 加上 –print0 是為了讓輸出的結果不以「斷行字元」分隔,而改以 null 為結果的分隔字元 

   註2: 使用 xargs 指令加上 –0 是為了讓傳入的資料以 null 字元當成參數的分隔 

   註3: 使用 rm 指令加上 –v 是為了能顯示出被刪除的檔案名稱,這個參數可以省略 

   註4: 使用 xargs 會將所有 find 指令查到的檔案轉換成 rm 的參數列,如果檔案過多可能會執行失敗! 

   註5: 使用 xargs 可確保後面的程式 ( rm ) 隻執行一次,是以理論上執行速度較快!

相同參數需輸入多筆並且以「或」邏輯運算時要用 –o 參數串接起來

例1:同時找兩種檔名樣式的檔案

find $HOME -name '*.mp3' -o -user '*.ogg'      

例2:同時找兩個擁有者的檔案

find /usr/local -user user1 -o -user user2      

【 注意事項 】

  • 使用萬用字元時務必加上單引號( ' ) 

    !!以下是錯誤示範!!

    [[email protected] ~]# find $HOME -name *.txt 

    find: paths must precede expression 

    Usage: find [path...] [expression]

find -exec -ok 的用法 -mtime
find -exec -ok 的用法 -mtime

繼續閱讀