這裡整理了一系列的 find 指令使用範例教學,對於管理或使用 Unix/Linux 的人很有幫助。

find 指令是 Unix/Linux 系統中很常用的指令之一,尤其是對於系統管理者,更是會常常使用到這個工具。

對於 Unix/Linux 系統的管理者而言,find 是一個很有用的指令,它支援非常多的搜尋選項,可以依照權限、擁有者、群組、檔案類型、日期與大小等條件來搜尋,這裡整理一些常用的 find 指令的一些使用技巧。

指定檔名搜尋

若要在目前的目錄底下,找尋檔案名稱為 gtwang.txt 的檔案,可以使用:

find . -name gtwang.txt

執行後,find 會列出所有檔名是 gtwang.txt 的檔案列表。

./gtwang/gtwang.txt

/home 目錄底下,找尋檔案名稱為 gtwang.txt 的檔案:

find /home -name gtwang.txt

輸出為

/home/gtwang/gtwang/gtwang.txt

/home 目錄底下,不分英文大小寫,找尋檔案名稱為 gtwang.txt 的檔案:

find /home -iname gtwang.txt

輸出為

/home/gtwang/gtwang/GTWang.txt
/home/gtwang/gtwang/GTWANG.TXT
/home/gtwang/gtwang/gtwang.txt

指定檔案類型搜尋

find-type 參數可以指定檔案的類型,常用的選項有:

  • d:目錄。
  • p:具名的 pipe(FIFO)。
  • f:一般的檔案。
  • l:連結檔,如果與 -L-follow 參數同時使用時,就只會搜尋到有問題的連結檔,如果想要與 -L 同時使用,請改用 -xtype
  • s:socket 檔案。

在根目錄底下搜尋名稱為 gtwang 的目錄:

find / -type d -name gtwang

輸出會像這樣

/home/gtwang
/home/gtwang/gtwang

列出目前目錄底下所有的 PHP 檔案:

find . -type f -name "*.php"

檔案權限

-perm 可以指定檔案的權限,例如列出權限是 777 的所有檔案:

find . -type f -perm 0777

這個指令在檢查系統漏洞時會常用到。另外我們也可以用排除的方式,列出所有權限不是 777 的檔案:

find . -type f ! -perm 777

find 也用來搜尋具有特殊權限的檔案,例如找尋權限是 644 而且有 SGID 的檔案(關於 SGID 可以參考鳥哥的文件):

find . -perm 2644

找尋權限是 644 而且有 Sticky Bit 的檔案:

find . -perm 1551

列出系統中所有 SUID 的檔案:

find / -perm /u=s

列出系統中所有 SGID 的檔案:

find / -perm /g+s

列出唯讀的檔案:

find / -perm /u=r

列出可執行的檔案:

find / -perm /a=x

執行指令

-exec 可以讓我們將搜尋出來的結果,使用其他的指令進行後續的處理動作,例如將目前目錄下所有權限為 777 的檔案找出來,用 chmod 將這些檔案的權限更改為 644

find . -type f -perm 0777 -print -exec chmod 644 {} \;

找出所有權限為 777 的目錄,將這些目錄用 chmod 把權限改為 755

find / -type d -perm 777 -print -exec chmod 755 {} \;

找出檔名為 gtwang.txt 的所有檔案,並且刪除它:

find . -type f -name "gtwang.txt" -exec rm -f {} \;

找出所有的 *.mp3 檔,並且刪除:

find . -type f -name "*.mp3" -exec rm -f {} \;

空檔案與隱藏檔

如果要找尋空檔案,可以使用 -empty 參數:

find . -type f -empty

找尋空目錄:

find . -type d -empty

在 UNIX/Linux 系統上的隱藏檔其實就是檔名以句點(.)開頭的檔案,若要找尋這些檔案可以執行:

find . -type f -name ".*"

檔案擁有者

使用 -user 參數可以在搜尋時加上檔案擁有者的條件,搜尋特定使用者的檔案,例如在根目錄下搜尋 root 管理者的 gtwang.txt 這個檔案:

find / -user root -name gtwang.txt

/home 之下找出 gtwang 使用者的所有檔案:

find /home -user gtwang

/home 之下找出 gtwang 使用者的所有 *.txt 文字檔,副檔名不分大小寫:

find /home -user gtwang -iname "*.txt"

使用 -group 參數可以指定檔案的群組,例如在 /home 之下搜尋所有 developer 群組的檔案:

find /home -group developer

檔案修改與存取日期

find 有一系列時間相關的參數:

-mtime n
指定檔案的最後修改時間(modification time),單位為天。
-mmin n
指定檔案的最後修改時間,單位為分鐘。
-atime n
指定檔案的最後存取時間(access time),單位為天。
-amin n
指定檔案的最後存取時間,單位為分鐘。
-ctime n
指定檔案狀態相關資訊最後修改的時間(status time),單位為天。
-cmin n
指定檔案狀態相關資訊最後修改的時間,單位為分鐘。

找尋剛好在 7 天之前有被修改過的檔案(例如今天是 9/17,那麼 7 天前就是 9/11):

find . -mtime 7

找尋最近 7 天之內有被修改過的檔案(例如今天是 9/17,那麼 7 天之內就是 9/11 到 9/17):

find . -mtime -7

找尋上次修改的時間是在 7 天以上的檔案(例如今天是 9/17,那麼修改時間在 7 天以上的檔案就是 9/11 以前修改過的檔案):

find . -mtime +7

找出上次修改的時間是在 7 天以上、14 天以下的檔案:

find . -mtime +7 -mtime -14

找尋最近一小時內更改過的檔案:

find . -mmin -60

基本上 mtimectimeatime 的時間指定方式都相同,例如找尋最近一小時內更改過狀態的檔案:

find . -cmin -60

找尋最近一小時內有被存取過的檔案:

find . -amin -60

關於 mtimectimeatime 的差異,可以參考鳥哥的文件

檔案大小

使用 -size 參數可以指定檔案的大小,例如搜尋檔案大小剛好是 50MB 的檔案:

find . -size 50M

找出檔案大小介於 50MB 到 100MB 之間的檔案:

find . -size +50M -size -100M

找出大於 100MB 的檔案,並且直接刪除之:

find . -size +100M -exec rm -rf {} \;

實用範例

在目前的目錄中,找出所有檔案大小在 10MB 以上的 mp3 檔案,並且直接刪除這些檔案:

find . -type f -name *.mp3 -size +10M -exec rm {} \;

在目前的目錄中,找出所有的 C 語言原始碼檔案(*.c),透過 grep 搜尋這些程式碼,過濾出含有 main 這個單字的檔案,列出所有符合條件的檔案列表:

find ./ -name \*.c -exec grep -wl main {} \;

輸出類似這樣:

./scripts/basic/bin2c.c
./scripts/basic/fixdep.c

下面這行指令一樣是搜尋 C 語言的原始碼,不過它可以顯示檔案的完整路徑(-H)、行號(-n)以及匹配處的以下 5 行(-A5):

find ./ -name \*.c -exec grep -wnHA5 main {} \;

這個指令的輸出會更有用:

./scripts/basic/bin2c.c:12:int main(int argc, char *argv[])
./scripts/basic/bin2c.c-13-{
./scripts/basic/bin2c.c-14-	int ch, total = 0;
./scripts/basic/bin2c.c-15-
./scripts/basic/bin2c.c-16-	if (argc > 1)
./scripts/basic/bin2c.c-17-		printf("const char %s[] %s=\n",
./scripts/basic/fixdep.c:447:int main(int argc, char *argv[])
./scripts/basic/fixdep.c-448-{
./scripts/basic/fixdep.c-449-	traps();
./scripts/basic/fixdep.c-450-
./scripts/basic/fixdep.c-451-	if (argc != 4)
./scripts/basic/fixdep.c-452-		usage();

若要顯示匹配處的以上 5 行,可以在 grep 指令上再加一個 -B5 參數。

參考資料:TecmintMartin’s blog 馬汀的部落格