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

檔案修改與存取日期

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

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

find . -cmin -60

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

find . -amin -60

關於 mtimectime 與 atime 的差異,可以參考鳥哥的文件

檔案大小

使用 -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 參數。