-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選項中
- # 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
在/ 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
任何形式的命令都可以在- 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命令的一般形式爲;
2、find命令的參數;
-print: find命令將匹配的文件輸出到標準輸出。
-exec: find命令對匹配的文件執行該參數所給出的shell命令。相應命令的形式爲'command' { } \;,注意{ }和\;之間的空格。
-ok: 和-exec的作用相同,只不過以一種更爲安全的模式來執行該參數所給出的shell命令,在執行每一個命令之前,都會給出提示,讓用戶來確定是否執行。
3、find命令選項
按照文件名查找文件。
-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命令,將這些文件備份到磁帶設備中。
查找系統中最後N分鐘訪問的文件
-atime n
查找系統中最後n*24小時訪問的文件
-cmin n
查找系統中最後N分鐘被改變文件狀態的文件
-ctime n
查找系統中最後n*24小時被改變文件狀態的文件
-mmin n
查找系統中最後N分鐘被改變文件數據的文件
-mtime n
查找系統中最後n*24小時被改變文件數據的文件
4、使用exec或ok來執行shell命令
-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
在/logs目錄中查找更改時間在5日以前的文件並刪除它們:
< rm ... ./conf/httpd.conf > ? n
sam:x:501:501::/usr/sam:/bin/bash
二、find命令的例子;
1、查找當前用戶主目錄下的所有文件:
$ find ~ -print
2、讓當前目錄中文件屬主具有讀、寫權限,並且文件所屬組的用戶和其他用戶具有讀權限的文件;
3、爲了查找系統中所有文件長度爲0的普通文件,並列出它們的完整路徑;
4、查找/var/logs目錄中更改時間在7日以前的普通文件,並在刪除之前詢問它們;
5、爲了查找系統中所有屬於root組的文件;
-rw-r--r-- 1 root root 595 10月 31 01:09 ./fie1
6、find命令將刪除當目錄中訪問時間在7日以來、含有數字後綴的admin.log文件。
rm { } \;
< rm ... ./admin.log001 > ? n
< rm ... ./admin.log002 > ? n
< rm ... ./admin.log042 > ? n
< rm ... ./admin.log942 > ? n
7、爲了查找當前文件系統中的所有目錄並排序;
8、爲了查找系統中所有的rmt磁帶設備;
三、xargs
./.kde/Autostart/Autorun.desktop: UTF-8 Unicode English text
./.kde/Autostart/.directory: ISO-8859 text\
......
# cat /temp/core.log
./file6
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
./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
./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 命令的參數
1、使用name選項
2、用perm選項
-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、忽略某個目錄
4、使用find查找文件的時候怎麼避開某個文件目錄
-print 的簡寫表達式按順序求值, -a 和 -o 都是短路求值,與 shell 的 && 和 || 類似如果 -path "/usr/sam" 爲真,則求值 -prune , -prune 返回真,與邏輯表達式爲真;否則不求值 -prune,與邏輯表達式爲假。如果 -path "/usr/sam" -a -prune 爲假,則求值 -print ,-print返回真,或邏輯表達式爲真;否則不求值 -print,或邏輯表達式爲真。
-prune
else
5、使用user和nouser選項
6、使用group和nogroup選項
7、按照更改時間或訪問時間等查找文件
8、查找比某個文件新或舊的文件
-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
9、使用type選項
10、使用size選項
在當前目錄下查找文件長度大於1 M字節的文件:
11、使用depth選項
12、使用mount選項
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
兩者效果相同
在unix或linux環境中經常會用到find -mtime這樣的寫法來找某某時間點之前的文件,至於如何寫find -mtime +N/-N/N,原來並不是很清楚,今天找了些資料看看,畫下了這個圖,以便理解和記憶:
從圖上可以看出,以當前時間點開始算起,+表示往左,從該時間點開始再繼續往更早推,可以稱作xx以外;-表示往右,從該時間點算起往後的時間推,可以稱作xx以內;沒有加減號表示據此此前第N天。因此:
我們來看下面這個例子:
我當前的時間2011年3月1日22:31,我有如下的文件:
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,在此前的文件,會被選出來。
./111.txt
./222.txt
-mtime +1,表示1天以外的,即從距當前時間的1天前算起,往更早的時間推移。因此2011-02-28 22:31前的文件屬於該結果,2011-02-28 22:31後的文件不屬於該結果:
./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,因此這段時間內的文件會被選中出來:
./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,因此這段時間內的文件會被選中出來:
./666.txt
-mtime -1 表示1天以內的,從距當前時間的1天爲2011-02-28 22:31,往右推移:
./
./666.txt
./777.txt
-mtime -2 表示2天以內的,從距當前時間的2天爲2011-02-27 22:31開始,往右推移:
./
./333.txt
./444.txt
./555.txt
./666.txt
./777.txt
還有種表述方式:find PATH OPTION [-exec COMMAND { } \;]
因爲find命令會根據我們給的option,也就是尋找條件從我們給出的目錄開始對其中文件及其下子目錄中的文件進行遞歸搜索,所以我覺的這個地方說是“起始目錄”是非常好的。
該命令中的尋找條件可以是一個用邏輯運算符 not、and、or 組成的複合條件。邏輯運 算符 and、or、not 的含義爲:
find –name ’tmp’ –xtype c -user ’inin’
% 該命令尋找三個給定條件都滿足的所有文件
find –name ’tmp’ –o –name ’mina*’
% 該命令查詢文件名爲’tmp’或是匹配’mina*’的所有文件。
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
【 注意事項 】
- 使用萬用字元時務必加上單引號( ' )
!!以下是錯誤示範!![user1@server ~]# find $HOME -name *.txt
find: paths must precede expression
Usage: find [path...] [expression]