Linux find 命令詳解
Linux 上的find
命令是findutil
軟體包的一部分,一般已經預設整合在了幾乎所有的發行版中。
find 命令有非常大的靈活性,可以向其指定豐富的搜尋條件(如檔案許可權 、屬主 、屬組 、檔案型別 、日期 和大小 等)來定位系統中的檔案和目錄。
此外,find 還支援對搜尋到的結果進行多種型別的命令 操作。
一、簡介
find 命令的基本結構如下:
find [paths] [expression] [actions]
find 命令接受一個或多個路徑 (paths )作為搜尋範圍,並在該路徑下遞迴 地搜尋。即檢索完指定的目錄後,還會對該目錄下的子目錄進行檢索,以及子目錄下的子目錄。。。直到到達目錄樹底部。
預設情況下(不帶任何搜尋條件),find 命令會返回指定目錄下的所有檔案
,所以常常需要通過特定的expression
對結果進行篩選
。
find 命令預設的action
是將所有檢索結果列印至標準輸出。可以通過自定義action
,讓 find 命令對搜尋到的結果執行特定的操作。
這裡先不做詳細解釋,簡單地測試下 find 命令:
- 有如下結構的示例目錄 directory
$ tree directory directory ├── file1 ├── file2 ├── sub-dir1 │├── file1 │├── file2 │└── file3 └── sub-dir2 ├── file2 └── sub-subdir1 └── file1 3 directories, 7 files
- 預設的 find 命令會列出該目錄下的所有檔案
$ find directory directory directory/sub-dir1 directory/sub-dir1/file3 directory/sub-dir1/file2 directory/sub-dir1/file1 directory/file2 directory/sub-dir2 directory/sub-dir2/file2 directory/sub-dir2/sub-subdir1 directory/sub-dir2/sub-subdir1/file1 directory/file1
- 為 find 命令指定 expression 以篩選出特定的檔案
$ find directory -name file2 directory/sub-dir1/file2 directory/file2 directory/sub-dir2/file2
-
為 find 命令指定特殊的 action(此處
-delete
表示刪除搜尋結果)
$ find directory -name file2 -delete $ find directory directory directory/sub-dir1 directory/sub-dir1/file3 directory/sub-dir1/file1 directory/sub-dir2 directory/sub-dir2/sub-subdir1 directory/sub-dir2/sub-subdir1/file1 directory/file1
二、搜尋條件(expression)
1. 根據檔名檢索
find 命令中的-name
選項可以根據檔名稱進行檢索(區分大小寫
)。如需要忽略檔名中的大小寫,可以使用-iname
選項。
-name
和-iname
兩個選項都支援wildcards
。如:
? *
find /usr -name '*.txt'
查詢 /usr 目錄下所有檔名以.txt
結尾的檔案
find /usr -name '????'
查詢 /usr 目錄下所有檔名剛好為 4 個字元的檔案
有些時候,你需要在搜尋時匹配某個檔案或目錄的完整路徑
,而不僅僅是匹配檔名。可以使用-path
或-ipath
選項。
如查詢 /usr 下所有檔名以.txt
結尾的檔案或目錄,且該檔案的父目錄必須是src
。可以使用以下命令:
find /usr -path '*/src/*.txt'
2. 根據檔案型別檢索
如果只想搜尋得到檔案或
目錄,即不想它們同時出現在結果中。可以使用-type
選項指定檔案型別。
-type
選項最常用的引數如下:
- f: 檔案
- d: 目錄
- l: 符號連結
find /usr -type d -name 'python*'
檢索 /usr 下所有檔名以python
開頭的目錄
3. 檢索空檔案
find 命令支援-empty
選項用來檢索為空
的檔案或目錄。空檔案即檔案裡沒有任何內容,空目錄即目錄中沒有任何檔案或子目錄。
find ~ -type d -empty
檢索使用者主目錄下所有的空目錄
4. 反義匹配
find 命令也允許使用者對當前的匹配條件進行“反義” (類似於邏輯非 操作)。
如需要檢索 /usr 下所有檔名不
以.txt
為字尾的檔案。可以使用以下命令:
find /usr -type f ! -name '*.txt'
也可以“翻轉”任何其他的篩選條件,如:
find /usr -type f ! -empty
檢索 /usr 下所有內容不為空的檔案
5. 根據檔案的所屬權檢索
為了檢索歸屬於特定使用者的檔案或目錄,可以使用-user
選項。
find / -type f -user starky
檢索根目錄下所有屬主為 starky 的檔案
類似於-user
選項,-group
選項則可以根據檔案或目錄的屬組
進行檢索。
6. 根據時間日期進行檢索
有些時候,需要根據檔案建立或修改的時間進行檢索。
Linux 系統中,與檔案相關聯的時間引數有以下三種:
- 修改時間(Modification time):最後一次檔案內容有過更改的時間點
- 訪問時間(Access time):最後一次檔案有被讀取過的時間點
- 變更時間(Change time):最後一次檔案有被變更 過的時間點(如內容被修改,或許可權等 metadata 被修改)
與此對應的是 find 命令中的-mtime
,-atime
和-ctime
三個選項。
這三個選項的使用遵循以下示例中的規則:
-
-mtime 2
:該檔案 2 天前被修改過 -
-mtime -2
:該檔案 2 天以內 被修改過 -
-mtime +2
:該檔案距離上次修改已經超過 2 天時間
find /usr -type f -mtime 2
檢索 /usr 下兩天前被修改過的檔案
如果覺得-mtime
等選項以天
為單位時間有點長,還可以使用-mmin
,-amin
,-cmin
三個選項:
find /usr -type f -mtime +50 -mtime -100
檢索 /usr 下 50 到 100 天之前修改過的檔案
find /usr -type f -mtime 2 -amin 5
檢索 /usr 下兩天前被修改過且 5 分鐘前又讀取過的檔案
7. 根據檔案大小檢索
-size
選項允許使用者通過檔案大小進行搜尋(只適用於檔案,目錄沒有大小……)。
表示檔案大小的單位由以下字元組成:
c k M G
另外,還可以使用+
或-
符號表示大於
或小於
當前條件。
find / -size +1G
檢索檔案大小高於 1 GB 的檔案
8. 根據檔案許可權檢索
find 命令可以使用-perm
選項以檔案許可權為依據進行搜尋。
使用符號形式
如需要檢索 /usr 目錄下許可權為rwxr-xr-x
的檔案,可以使用以下命令:
find /usr -perm u=rwx,g=rx,o=rx
搜尋 /usr 目錄下所有許可權為r-xr-xr-x
(即系統中的所有使用者都只有讀寫許可權)的檔案和目錄,可以使用以下命令:
find /usr -perm a=rx
很多時候,我們只想匹配檔案許可權的一個子集 。比如,檢索可以直接被任何使用者執行的檔案,即只關心檔案的執行許可權,而不用管其讀寫許可權是什麼。
上述的需求可以通過以下命令實現:find / -type f -perm /a=x
其中a=x
前面的/
符號即用來表示只匹配許可權的某個子集(執行許可權),而不用關心其他許可權的具體設定。
使用數字形式
-perm
選項也支援數字形式的檔案許可權標記。
find /usr -perm 644
搜尋 /usr 目錄下許可權為644
(即rwxr-xr-x
)的檔案
9. 限制遍歷的層數
find 命令預設是以遞迴
的方式檢索專案的,這有時候會導致得到的結果數量非常巨大。可以使用-maxdepth
限制 find 命令遞迴的層數。
find / -maxdepth 3
搜尋時向下遞迴的層數最大為 3
10. 邏輯組合
在之前的例子中有出現多個搜尋條件的組合 以及對某個搜尋條件的反轉 。
實際上 find 命令支援“and”
和“or”
兩種邏輯運算,對應的命令選項分別是-a
和-o
。通過這兩個選項可以對搜尋條件進行更復雜的組合。
此外還可以使用小括號
對搜尋條件進行分組
。注意find
命令中的小括號常需要用單引號
包裹起來。因小括號在 Shell 中有特殊的含義。
如檢索 /usr 下檔名以python
開頭且型別為目錄的檔案
find /usr -type d -name 'python*'
該命令等同於:
find /usr -type d -a -name 'python*'
更復雜的組合形式如:
find / '(' -mmin -5 -o -mtime +50 ')' -a -type f
三、對搜尋結果執行命令
1. 刪除檔案
-delete
選項可以用來刪除搜尋到的檔案和目錄。
如刪除 home 目錄下所有的空目錄:
find ~ -type d -empty -delete
2. 執行自定義命令
-exec
選項可以對搜尋到的結果執行特定的命令。
如需要將 home 目錄下所有的 MP3 音訊檔案複製到移動儲存裝置(假設路徑是/media/MyDrive
),可使用下面的命令:
find ~ -type f -name '*.mp3' -exec cp {} /media/MyDrive ';'
其中的大括號
({}
)作為檢索到的檔案的佔位符
,而分號(;
)作為命令結束的標誌。因為分號是 Shell 中有特殊含義的符號,所以需要使用單引號括起來。
每當 find 命令檢索到一個符合條件的檔案,會使用其完整路徑取代命令中的{}
,然後執行-exec
後面的命令一次。
另一個很重要的用法是,在多個檔案中檢索某個指定的字串。
如在使用者主目錄下的所有檔案中檢索字串hello
,可以使用如下命令:
find ~ -type f -exec grep -l hello {} ';'
-exec 選項中的 + 符號
建立 Gzip 格式的壓縮檔案的命令為:tar -czvf filename.tar.gz <list of files>
現在假設需要將使用者主目錄下所有的 MP3 檔案新增到壓縮包music.tar.gz
中,直觀的感覺是,其命令應為如下形式:
find ~ -type f -name '*.mp3' -exec tar -czvf music.tar.gz {} ';'
實際情況是,這樣得到的music.tar.gz
其實只包含一個 MP3 檔案。
原因是 find 命令每次
發現一個音訊檔案,都會再執行一次-exec
選項後面的壓縮命令。導致先前生成的壓縮包被覆蓋。
可以先讓 find 命令檢索出所有符合條件的音訊檔案,再將得到的檔案列表 傳遞給後面的壓縮命令。完整的命令如下:
find ~ -type f -name '*.mp3' -exec tar -czvf music.tar.gz {} +
顯示檔案資訊
如果想瀏覽搜尋到的檔案(目錄)的詳細資訊(如許可權和大小等),可以直接使用-ls
選項。
find / -type file -size +1G -ls
瀏覽所有 1G 以上大小的檔案的詳細資訊
四、常用引數彙總
引數 | 解析 |
---|---|
-atimen[smhdw] | 距離檔案上次被訪問時的時間間隔 |
-ctimen[smhdw] | 距離檔案建立時的時間間隔 |
-delete | 刪除檢索到的檔案 |
-depthn | 檢索深度為 n 的檔案,即位於指定目錄以下 n 層的檔案 |
-empty | 檢索空檔案或空目錄 |
-fstypetype | 指定檔案所在的檔案系統的型別 |
-groupgname | 指定檔案的屬組 |
-inamepattern |
同-name
,忽略大小寫 |
-ipathpattern |
同-path
,忽略大小寫 |
-ls | 列印搜尋到的檔案的詳細資訊 |
-maxdepthn | 指定遞迴的最大層數為 n |
-mtimen[smhdw] | 距離檔案上次發生變更時的時間間隔 |
-namepattern |
搜尋時使用pattern
對檔名進行匹配 |
-pathpattern |
搜尋時使用pattern
對檔案路徑進行匹配 |
-permmode | 根據檔案許可權搜尋 |
-sizen[ckMGTP] | 根據檔案大小搜尋 |
-typet | 根據檔案型別搜尋 |
-useruname | 指定檔案的屬主 |
參考資料
ofollow,noindex">A Guide to the Linux “Find” Command
find 命令手冊:man find