Linux 上的
find命令是findutil軟件包的一部分,一般已經(jīng)默認集成在了幾乎所有的發(fā)行版中。
find 命令有非常大的靈活性,可以向其指定豐富的搜索條件(如文件權(quán)限、屬主、屬組、文件類型、日期和大小等)來定位系統(tǒng)中的文件和目錄。
此外,find 還支持對搜索到的結(jié)果進行多種類型的命令操作。
一、簡介
find 命令的基本結(jié)構(gòu)如下:
find [paths] [expression] [actions]
find 命令接受一個或多個路徑(paths)作為搜索范圍,并在該路徑下遞歸地搜索。即檢索完指定的目錄后,還會對該目錄下的子目錄進行檢索,以及子目錄下的子目錄。。。直到到達目錄樹底部。
默認情況下(不帶任何搜索條件),find 命令會返回指定目錄下的所有文件,所以常常需要通過特定的 expression 對結(jié)果進行篩選。
find 命令默認的 action 是將所有檢索結(jié)果打印至標準輸出??梢酝ㄟ^自定義 action ,讓 find 命令對搜索到的結(jié)果執(zhí)行特定的操作。
這里先不做詳細解釋,簡單地測試下 find 命令:
- 有如下結(jié)構(gòu)的示例目錄 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表示刪除搜索結(jié)果)
$ 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. 根據(jù)文件名檢索
find 命令中的 -name 選項可以根據(jù)文件名稱進行檢索(區(qū)分大小寫)。如需要忽略文件名中的大小寫,可以使用 -iname 選項。
-name 和 -iname 兩個選項都支持 wildcards 。如:
-
?可以表示任意一個單一的符號 -
*可以表示任意數(shù)量(包括 0)的未知符號
find /usr -name '*.txt' 查找 /usr 目錄下所有文件名以 .txt 結(jié)尾的文件
find /usr -name '????' 查找 /usr 目錄下所有文件名剛好為 4 個字符的文件
有些時候,你需要在搜索時匹配某個文件或目錄的完整路徑,而不僅僅是匹配文件名??梢允褂?-path 或 -ipath 選項。
如查找 /usr 下所有文件名以 .txt 結(jié)尾的文件或目錄,且該文件的父目錄必須是 src??梢允褂靡韵旅睿?br>
find /usr -path '*/src/*.txt'
2. 根據(jù)文件類型檢索
如果只想搜索得到文件或目錄,即不想它們同時出現(xiàn)在結(jié)果中??梢允褂?-type 選項指定文件類型。
-type 選項最常用的參數(shù)如下:
- f: 文件
- d: 目錄
- l: 符號鏈接
find /usr -type d -name 'python*' 檢索 /usr 下所有文件名以 python 開頭的目錄
3. 檢索空文件
find 命令支持 -empty 選項用來檢索為空的文件或目錄。空文件即文件里沒有任何內(nèi)容,空目錄即目錄中沒有任何文件或子目錄。
find ~ -type d -empty 檢索用戶主目錄下所有的空目錄
4. 反義匹配
find 命令也允許用戶對當前的匹配條件進行“反義”(類似于邏輯非操作)。
如需要檢索 /usr 下所有文件名不以 .txt 為后綴的文件??梢允褂靡韵旅睿?br>
find /usr -type f ! -name '*.txt'
也可以“翻轉(zhuǎn)”任何其他的篩選條件,如:
find /usr -type f ! -empty 檢索 /usr 下所有內(nèi)容不為空的文件
5. 根據(jù)文件的所屬權(quán)檢索
為了檢索歸屬于特定用戶的文件或目錄,可以使用 -user 選項。
find / -type f -user starky 檢索根目錄下所有屬主為 starky 的文件
類似于 -user選項,-group 選項則可以根據(jù)文件或目錄的屬組進行檢索。
6. 根據(jù)時間日期進行檢索
有些時候,需要根據(jù)文件創(chuàng)建或修改的時間進行檢索。
Linux 系統(tǒng)中,與文件相關(guān)聯(lián)的時間參數(shù)有以下三種:
- 修改時間(Modification time):最后一次文件內(nèi)容有過更改的時間點
- 訪問時間(Access time):最后一次文件有被讀取過的時間點
- 變更時間(Change time):最后一次文件有被變更過的時間點(如內(nèi)容被修改,或權(quán)限等 metadata 被修改)
與此對應(yīng)的是 find 命令中的 -mtime,-atime 和 -ctime 三個選項。
這三個選項的使用遵循以下示例中的規(guī)則:
-
-mtime 2:該文件 2 天前被修改過 -
-mtime -2:該文件 2 天以內(nèi)被修改過 -
-mtime +2:該文件距離上次修改已經(jīng)超過 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. 根據(jù)文件大小檢索
-size 選項允許用戶通過文件大小進行搜索(只適用于文件,目錄沒有大小……)。
表示文件大小的單位由以下字符組成:
-
c:字節(jié) -
k:Kb -
M:Mb -
G:Gb
另外,還可以使用 + 或 - 符號表示大于或小于當前條件。
find / -size +1G 檢索文件大小高于 1 GB 的文件
8. 根據(jù)文件權(quán)限檢索
find 命令可以使用 -perm 選項以文件權(quán)限為依據(jù)進行搜索。
使用符號形式
如需要檢索 /usr 目錄下權(quán)限為 rwxr-xr-x 的文件,可以使用以下命令:
find /usr -perm u=rwx,g=rx,o=rx
搜索 /usr 目錄下所有權(quán)限為 r-xr-xr-x(即系統(tǒng)中的所有用戶都只有讀寫權(quán)限)的文件和目錄,可以使用以下命令:
find /usr -perm a=rx
很多時候,我們只想匹配文件權(quán)限的一個子集。比如,檢索可以直接被任何用戶執(zhí)行的文件,即只關(guān)心文件的執(zhí)行權(quán)限,而不用管其讀寫權(quán)限是什么。
上述的需求可以通過以下命令實現(xiàn):find / -type f -perm /a=x
其中 a=x 前面的 / 符號即用來表示只匹配權(quán)限的某個子集(執(zhí)行權(quán)限),而不用關(guān)心其他權(quán)限的具體設(shè)置。
使用數(shù)字形式
-perm 選項也支持數(shù)字形式的文件權(quán)限標記。
find /usr -perm 644 搜索 /usr 目錄下權(quán)限為 644(即 rwxr-xr-x)的文件
9. 限制遍歷的層數(shù)
find 命令默認是以遞歸的方式檢索項目的,這有時候會導致得到的結(jié)果數(shù)量非常巨大??梢允褂?-maxdepth 限制 find 命令遞歸的層數(shù)。
find / -maxdepth 3 搜索時向下遞歸的層數(shù)最大為 3
10. 邏輯組合
在之前的例子中有出現(xiàn)多個搜索條件的組合以及對某個搜索條件的反轉(zhuǎn)。
實際上 find 命令支持 “and” 和 “or” 兩種邏輯運算,對應(yīng)的命令選項分別是 -a 和 -o。通過這兩個選項可以對搜索條件進行更復(fù)雜的組合。
此外還可以使用小括號對搜索條件進行分組。注意 find 命令中的小括號常需要用單引號包裹起來。因小括號在 Shell 中有特殊的含義。
如檢索 /usr 下文件名以 python 開頭且類型為目錄的文件
find /usr -type d -name 'python*'
該命令等同于:
find /usr -type d -a -name 'python*'
更復(fù)雜的組合形式如:
find / '(' -mmin -5 -o -mtime +50 ')' -a -type f
三、對搜索結(jié)果執(zhí)行命令
1. 刪除文件
-delete 選項可以用來刪除搜索到的文件和目錄。
如刪除 home 目錄下所有的空目錄:
find ~ -type d -empty -delete
2. 執(zhí)行自定義命令
-exec 選項可以對搜索到的結(jié)果執(zhí)行特定的命令。
如需要將 home 目錄下所有的 MP3 音頻文件復(fù)制到移動存儲設(shè)備(假設(shè)路徑是 /media/MyDrive),可使用下面的命令:
find ~ -type f -name '*.mp3' -exec cp {} /media/MyDrive ';'
其中的大括號({})作為檢索到的文件的 占位符 ,而分號( ;)作為命令結(jié)束的標志。因為分號是 Shell 中有特殊含義的符號,所以需要使用單引號括起來。
每當 find 命令檢索到一個符合條件的文件,會使用其完整路徑取代命令中的 {},然后執(zhí)行 -exec 后面的命令一次。
另一個很重要的用法是,在多個文件中檢索某個指定的字符串。
如在用戶主目錄下的所有文件中檢索字符串 hello ,可以使用如下命令:
find ~ -type f -exec grep -l hello {} ';'
-exec 選項中的 + 符號
創(chuàng)建 Gzip 格式的壓縮文件的命令為:tar -czvf filename.tar.gz <list of files>
現(xiàn)在假設(shè)需要將用戶主目錄下所有的 MP3 文件添加到壓縮包 music.tar.gz 中,直觀的感覺是,其命令應(yīng)為如下形式:
find ~ -type f -name '*.mp3' -exec tar -czvf music.tar.gz {} ';'
實際情況是,這樣得到的 music.tar.gz 其實只包含一個 MP3 文件。
原因是 find 命令每次發(fā)現(xiàn)一個音頻文件,都會再執(zhí)行一次 -exec 選項后面的壓縮命令。導致先前生成的壓縮包被覆蓋。
可以先讓 find 命令檢索出所有符合條件的音頻文件,再將得到的文件列表傳遞給后面的壓縮命令。完整的命令如下:
find ~ -type f -name '*.mp3' -exec tar -czvf music.tar.gz {} +
顯示文件信息
如果想瀏覽搜索到的文件(目錄)的詳細信息(如權(quán)限和大小等),可以直接使用 -ls 選項。
find / -type file -size +1G -ls 瀏覽所有 1G 以上大小的文件的詳細信息
四、常用參數(shù)匯總
| 參數(shù) | 解析 |
|---|---|
| -atime n[smhdw] | 距離文件上次被訪問時的時間間隔 |
| -ctime n[smhdw] | 距離文件創(chuàng)建時的時間間隔 |
| -delete | 刪除檢索到的文件 |
| -depth n | 檢索深度為 n 的文件,即位于指定目錄以下 n 層的文件 |
| -empty | 檢索空文件或空目錄 |
| -fstype type | 指定文件所在的文件系統(tǒng)的類型 |
| -group gname | 指定文件的屬組 |
| -iname pattern | 同 -name,忽略大小寫 |
| -ipath pattern | 同 -path,忽略大小寫 |
| -ls | 打印搜索到的文件的詳細信息 |
| -maxdepth n | 指定遞歸的最大層數(shù)為 n |
| -mtime n[smhdw] | 距離文件上次發(fā)生變更時的時間間隔 |
| -name pattern | 搜索時使用 pattern 對文件名進行匹配 |
| -path pattern | 搜索時使用 pattern 對文件路徑進行匹配 |
| -perm mode | 根據(jù)文件權(quán)限搜索 |
| -size n[ckMGTP] | 根據(jù)文件大小搜索 |
| -type t | 根據(jù)文件類型搜索 |
| -user uname | 指定文件的屬主 |
參考資料
A Guide to the Linux “Find” Command
find 命令手冊:man find