2008年8月12日 星期二

linux指令-find


[root@host ~]# find [PATH] [option] [action]
[範例]
[root@host ~]# find / -name 'file1' <==在根目錄下尋找名為file1的檔案
[root@host ~]# find ./ -name '*file*' <==在目前的目錄下尋找檔名包含file的檔案

這一個指令是目前直接去尋找目前的檔案系統,
因此,若是收尋的範圍是整個系統的話,那對硬碟負擔會很大。
這個時候我們建議另一個指令locate

我們常常不是把符合我要的條件的檔案找出來而已,通常我們還會直接對具有規則性的修改,這個時候find就很好用了
像我最近由光碟中把某一個目錄下的檔案複製到我的桌面,但是,一直沒有辦法修改,之後發現是所有檔案都不具有write的權限,我當然可以一個一個去修改,但是,「做重覆的事情是罪惡的」,嗯,find剛好可以解決我的問題


[範例]:把/home/Desktop/newfile下的所有檔案找出來,並且把這一些檔案加入write的權限
[root@host ~]# find /home/Desktop/newfile -exec chmod +w {} \;
exec後面的chmod就是額外的指令
{}就是表示find指令找出的結果(集合)
透過exec則必需要使用\;作為結尾


[2009.04.15 補充]
今天補充一些比較進階的功能:經過這一陣子的使用,find真的是一個非常好用的程式,一定要學滴~

$ find [PATH] [option] [action]
選項與參數:
1. 與時間有關的選項:共有 -atime, -ctime 與 -mtime ,以 -mtime 說明
-mtime  n :n 為數字,意義為在 n 天之前的『一天之內』被更動過內容的檔案;
-mtime +n :列出在 n 天之前(不含 n 天本身)被更動過內容的檔案檔名;
-mtime -n :列出在 n 天之內(含 n 天本身)被更動過內容的檔案檔名。
-newer file :file 為一個存在的檔案,列出比 file 還要新的檔案檔名

2. 與使用者或群組名稱有關的參數:
-uid n :n 為數字,這個數字是使用者的帳號 ID,亦即 UID ,這個 UID 是記錄在/etc/passwd 裡面與帳號名稱對應的數字。這方面我們會在第四篇介紹。
-gid n :n 為數字,這個數字是群組名稱的 ID,亦即 GID,這個 GID 記錄在/etc/group
-user name :name 為使用者帳號名稱喔!例如 dmtsai 
-group name:name 為群組名稱喔,例如 users ;
-nouser    :尋找檔案的擁有者不存在 /etc/passwd 的人!
-nogroup   :尋找檔案的擁有群組不存在於 /etc/group 的檔案!當你自行安裝軟體時,很可能該軟體的屬性當中並沒有檔案擁有者,這是可能的!在這個時候,就可以使用 -nouser 與 -nogroup 搜尋。

3. 與檔案權限及名稱有關的參數:
-name filename:搜尋檔案名稱為 filename 的檔案;
-size [+-]SIZE:搜尋比 SIZE 還要大(+)或小(-)的檔案。這個 SIZE 的規格有:c: 代表 byte, k: 代表 1024bytes。所以,要找比 50KB還要大的檔案,就是『 -size +50k 』
-type TYPE    :搜尋檔案的類型為 TYPE 的,類型主要有:一般正規檔案 (f),裝置檔案 (b, c), 目錄 (d), 連結檔 (l), socket (s), 及 FIFO (p) 等屬性。
-perm mode  :搜尋檔案權限『剛好等於』 mode 的檔案,這個 mode 為類似 chmod的屬性值,舉例來說, -rwsr-xr-x 的屬性為 4755 !
-perm -mode :搜尋檔案權限『必須要全部囊括 mode 的權限』的檔案,舉例來說,我們要搜尋 -rwxr--r-- ,亦即 0744 的檔案,使用 -perm -0744,當一個檔案的權限為 -rwsr-xr-x ,亦即 4755 時,也會被列出來,因為 -rwsr-xr-x 的屬性已經囊括了 -rwxr--r-- 的屬性了。
-perm +mode :搜尋檔案權限『包含任一 mode 的權限』的檔案,舉例來說,我們搜尋 -rwxr-xr-x ,亦即 -perm +755 時,但一個檔案屬性為 -rw-------也會被列出來,因為他有 -rw.... 的屬性存在!

4. 額外可進行的動作:
-exec command :command 為其他指令,-exec 後面可再接額外的指令來處理搜尋到的結果。
-print        :將結果列印到螢幕上,這個動作是預設動作!


[2010.01.01 補充]
在尋找檔案時,把某一些檔案排除在外
% find -maxdepth 1 -inmae '*.cpp' -not 'main.cpp" | xargs rm

[2010.09.22 補充]
在Windows下使用find(安裝GnuWin32),要注意的是,當要使用-exec的指令時,與Unix下面有所不同~
例: 把目前目錄(包含子目錄)下面把*.c檔中,每一行後面多餘的空白全部刪除
在Unix下
% find . -iname '*.c' -type f -exec sed 's/ \+$//g' {} \;
在Windows下
% find . -iname "*.c" -type f -exec sed "s/ \+$//g" {} ;

在Windows下與Unix下的主要差別在於'必需用"取代,而在;前面不需要加\符號
若在Windows下的分號前面加\會出現GnuWin32 find and missing argument for exec的錯誤

[2014.04.14 補充]
尋找目前的目錄(包含子目錄)的所有.h檔,但是並不收尋名為.svn的子目錄
% find . -path '.svn' -prune -o -name '*.h'

把找到的.h檔案去尋找其內容,尋找find_address字串出現在何處
% find . -path '.svn' -prune -o -name '*.h' -exec grep find_address -Hrn {} \;
grep -H表示顯示檔案名稱
grep -n表示顯示在檔案的行數

參考資料:
鳥哥的私房菜
GnuWin32 find and missing argument for exec

沒有留言: