Linux 文件搜索神器 find 實(shí)戰(zhàn)詳解
在 Linux 系統(tǒng)使用中,作為一個(gè)管理員,我希望能查找系統(tǒng)中所有的大小超過(guò) 200M 文件,查看近 7 天系統(tǒng)中哪些文件被修改過(guò),找出所有子目錄中的可執(zhí)行文件,這些任務(wù)需求 find 命令都可以輕松勝任。
在 Linux 系統(tǒng)文件中常用的屬性可以分為以下內(nèi)容:名稱、大小、權(quán)限、屬主、修改時(shí)間、訪問(wèn)時(shí)間等,find 命令可以按照指定的屬性為條件進(jìn)行查找。
廢話不多,直接開干,下邊進(jìn)入案例實(shí)戰(zhàn)。
案例實(shí)戰(zhàn)
(一)按文件名稱查找
按照文件名稱查找是 find 最常見的用法,需要注意的是,搜索的文件名必須完全匹配,才能找到對(duì)應(yīng)的文件。
1. 查找當(dāng)前目錄下所有 go 文件
$?find?.?-name?"*.go"
2. 在 etc 目錄下,查找大寫字母開頭的 txt 文件
$?find?/etc?-name?"[A-Z]*.txt"?-print
3. 在當(dāng)前目錄下查找不是 out 開頭的 txt 文件
$?find?.?-name?"out*"?-prune?-o?-name?"*.txt"?-print
4. 在當(dāng)前目錄除 git 子目錄外查找 txt 文件
$?find?.?-path?"./git"?-prune?-o?-name?"*.txt"?-print
5. 找出某個(gè)文件的所有硬鏈接,ls 命令 -i 選項(xiàng)可以查看文件的 inode 號(hào)
$?ls?-i?1.txt
138956?1.txt
$?find?.?-num?138956
搜索文件時(shí)使用 -iname 參數(shù)可以忽略文件名稱大小寫
(二)按文件類型查找
1. 在當(dāng)前目錄下,查找軟連接文件
$?find?.?-type?l?-print
2. 在當(dāng)前目錄下,查找 log 結(jié)尾的普通文件,f 表示普通文件類型
$?find?.?-type?f?-name?"*.log"
(三)按文件大小查找
1. 查找小于 64k 的文件
$?find?.?-size?-64k?-print
2. 查找大小超過(guò) 200M 的文件
$?find?.?-size?+200M?-type?f?-print
(四)按時(shí)間查找
1. 查找 2 天內(nèi)被修改過(guò)的文件
$?find?.?-mtime?-2?-type?f?-print
2. 查找 2 天前被更改過(guò)的文件,-mtime 表示內(nèi)容修改時(shí)間
$?find?.?-mtime?+2?-type?f?-print
3. 查找一天內(nèi)被訪問(wèn)的文件,-atime 表示訪問(wèn)時(shí)間
$?find?.?-atime?-1?-type?f?-print
4. 查找一天內(nèi)狀態(tài)被改變的文件,-ctime 表示元數(shù)據(jù)被變化時(shí)間
$?find?.?-ctime?-1?-type?f?-print
5. 查找比 chopin.txt 新的文件
$?find?.?-newer?"chopin.txt"?-type?f?-print
$?find?.?!?-newer?"chopin.txt"?-type?f?-print?#?舊
(五)根據(jù)權(quán)限查找
1. 查找當(dāng)前目錄權(quán)限為 644 的文件
$?find?.?-type?f?-perm?644
2. 查找 etc 目錄下至少有一個(gè)用戶有寫權(quán)限的文件
$?find?/etc?-type?f?-perm?/222
3. 查找 etc 目錄下所有用戶都有執(zhí)行權(quán)限的文件
$?find?/etc?-perm?-111?-ls
(六)組合條件
1. 查找當(dāng)前目錄下屬于 chopin 用戶的普通文件,-a 可以省略
$?find?.?-type?f?-a?-user?chopin?-print
2. 查找當(dāng)前目錄下大于 2M 或 2 天前被修過(guò)的文件
$?find?.?-size?+2M?-o?-mtime?+2?-print
3. 查找當(dāng)前目錄下不是普通文件
$?find?.?-not?-type?f
$?find?.?!?-type?f
4. 查找非空文件
$?find?.?!?-empty
(七)處理動(dòng)作
find 根據(jù)上述各種條件查找后,支持執(zhí)行相關(guān)的處理動(dòng)作,可以讓我們的更方便和靈活,而不只是打印出來(lái)
1. -print 默認(rèn)為打印,可省略
$?find?.?-name?"*.log"?-print
$?find?.?-name?"*.log"?#?等價(jià)
2. -ls 以 ls 長(zhǎng)文件的格式形式輸出
$?find?.?-name?"*.txt"?-ls
138957??????4?-rw-r--r--???1?root?????root???????????16?Jan?24?23:20?./a.txt
138959??????4?-rw-r--r--???1?root?????root??????????172?Jan?24?13:06?./T.txt
138956??????4?-rw-r--r--???1?root?????root???????????27?Jan?24?23:28?./1.txt
3. -delete 刪除查找到的文件
$?find?.?-size?+100M?-delete
4. -exec 將查找到的文件傳遞給 command 命令。下邊例子是將查找到的文件傳遞給了 ls 命令,同理我們可以傳遞給任何一個(gè) Linux 命令,功能十分強(qiáng)大,也很靈活。
$?find?.?-name?"*.txt"?-exec?ls?-lh?{}?\;
-rw-r--r--?1?root?root?16?Jan?24?23:20?./a.txt
-rw-r--r--?1?root?root?172?Jan?24?13:06?./T.txt
-rw-r--r--?1?root?root?27?Jan?24?23:28?./1.txt
5. -ok 與 -exec 功能一樣,只是操作時(shí)會(huì)提示用戶確認(rèn),僅此而已。當(dāng)然,在生產(chǎn)環(huán)境上,我們還是推薦使用 ok
(八)經(jīng)典案例
如果存在一個(gè)名稱亂碼的文件,想要?jiǎng)h除它,該怎么辦?即使我們復(fù)制亂碼名稱到命令行,很有可能終端不能正確識(shí)別。不用擔(dān)心,下邊來(lái)展示下 find 是如何優(yōu)雅的解決問(wèn)題的。
$?ls??-i
138957?a.txt??138959?T.txt??132395????.txt
$?find?.?-inum?132395?-exec?rm?{}?\;
命令中,-inum 指定的是文件的 inode 號(hào),它是系統(tǒng)中每個(gè)文件對(duì)應(yīng)的唯一編號(hào),find 通過(guò)編號(hào)找到后,執(zhí)行刪除操作。
總結(jié)歸納
find 命令是 Linux 命令中最有用的命令之一,它的功能非常強(qiáng)大,且語(yǔ)法復(fù)雜。其實(shí)我們不一定需要了解它的所有細(xì)節(jié),掌握上述實(shí)戰(zhàn)案例中的常見用法,足夠滿足日常工作中的大部分需求。
下邊我們一起來(lái)總結(jié)下 find 命令常見用法,加深對(duì) find 使用方法的理解。
命令格式
find path -option [-exec ...]
按文件名查找
-name:按照文件名稱查找,準(zhǔn)確匹配;-iname:不區(qū)分文件名的大小寫;-inode:按照文件 inode 號(hào)查找;
按照文件類型查找
按照文件類型查找,可以使用 -type 選項(xiàng),具體支持的文件類型如下:
f:普通文件d:目錄文件l:鏈接文件s:套接字文件p:管道文件b:塊設(shè)備文件,比如:磁盤c:字符設(shè)備文件,比如:鍵盤、鼠標(biāo)、網(wǎng)卡
按照文件從屬關(guān)系查找
-user:以用戶名查找-group:以組名查找-uid:以用戶 ID 查找-gid:以組 ID 查找-nouser:查找沒(méi)有屬主的文件-nogroup:查找沒(méi)有屬組的文件
按照文件大小查找
按照文件大小查找功能十分常用,用 -size 選項(xiàng),選項(xiàng)后邊指定大小 1024M,表示大小的格式有如下幾種:
-5M:查找小于 5M 的文件+5M:查找大于 5M 的文件5M:查找大小為 5M 的文件
單位支持的有 c(字節(jié))、k、M、G 等,需要注意的是默認(rèn)單位并不是字節(jié),而是 b,大小為 512 字節(jié)。
按照時(shí)間查找
按照時(shí)間查找的功能對(duì)系統(tǒng)管理員來(lái)說(shuō),十分常用,find 支持如下幾種時(shí)間類型:
atime:以訪問(wèn)時(shí)間查找mtime:以數(shù)據(jù)修改時(shí)間查找ctime:以元數(shù)據(jù)修改時(shí)間查找newer:以文件為條件,判斷比它新的文件
按時(shí)間查找時(shí),使用格式如下:
-atime -5:表示 5 天內(nèi)訪問(wèn)過(guò)的文件;-atime +5:表示 6 天前訪問(wèn)過(guò)的文件;-atime 5:表示前 5-6 那一天訪問(wèn)的文件;
這個(gè) +5 含義總是被人理解錯(cuò),誤認(rèn)為是 5 天后修改的文件,如果能知道未來(lái) 5 天的事情,小編早就去買彩票了!可能這么說(shuō)還不是很清楚,直接看圖吧!

find 不僅可以按 天 為單位來(lái)查找文件,可以按照 amin、mmin、cmin 來(lái)查找,區(qū)別只是 min 選項(xiàng)單位為分鐘。
按照權(quán)限查找
按權(quán)限查找是通過(guò) -perm 選項(xiàng),可以按照如下方式使用:
-perm 644:精確權(quán)限查找-perm /666:任何一類用戶中的任何一位符合條件即滿足-perm -222:每一類用戶的每一位同時(shí)符合條件即滿足
組合條件
find 可以使用多個(gè)條件的組合,支持 -a、-o、-not 或 !,比較簡(jiǎn)單,不再詳細(xì)描述其含義。
處理動(dòng)作
find 根據(jù)各種條件查找后,支持執(zhí)行相關(guān)的處理動(dòng)作,可以讓我們的更方便和靈活,而不只是打印出來(lái)。
-print:打印,默認(rèn)動(dòng)作,可省略-ls:以 ls 長(zhǎng)文件格式輸出-delete:刪除查找到的文件-exec:查找到的文件傳遞給任何 Linux 命令-ok:與 exec 功能相同,區(qū)別是需要用戶確認(rèn)每次的操作
再啰嗦一下,find 命令支持的參數(shù)和選項(xiàng)比較多,文中只是總結(jié)出最常用、核心的參數(shù)選項(xiàng)。如果上述命令確實(shí)不滿足需求,可以請(qǐng)教你的男人 man find。
這里需要提一下,find 搜索文件時(shí)通過(guò)掃描磁盤來(lái)進(jìn)行的,盡可能不要大范圍的搜索文件,尤其是在 / 目錄下搜索,會(huì)長(zhǎng)時(shí)間消耗服務(wù)器的 cpu 資源。如果是生產(chǎn)環(huán)境的機(jī)器,執(zhí)行前要考慮是否會(huì)對(duì)業(yè)務(wù)造成影響。
擴(kuò)展 locate
雖然 find 功能非常強(qiáng)大,但要知道的是,find 執(zhí)行過(guò)程是通過(guò)掃描磁盤文件來(lái)進(jìn)行查找的,如果大范圍的查找文件,需要花費(fèi)的時(shí)間很長(zhǎng),且消耗服務(wù)器 cpu 資源。
這里推薦另一個(gè) Linux 文件查找神器 locate,類似于 win 平臺(tái)下的 everything。它基于索引表進(jìn)行查詢,查詢速度非??欤静徽加?cpu 資源。
使用方法非常簡(jiǎn)單
$?locate?file.txt
$?locate?/etc/httpd
需要注意,如果是當(dāng)天新創(chuàng)建的文件,通過(guò) locate 默認(rèn)是查不到的,因?yàn)樗臄?shù)據(jù)庫(kù)默認(rèn)是每天自動(dòng)更新一次。如果希望查詢到當(dāng)天創(chuàng)建的新文件,需要執(zhí)行 updatedb 即可。
查找速度快是 locate 的優(yōu)勢(shì),但它的缺點(diǎn)也非常明顯:
模糊查詢 查找匹配模式單一 查詢的名稱匹配路徑命令 索引表的建立會(huì)占用磁盤空間 非實(shí)時(shí)查詢,當(dāng)天數(shù)據(jù)可能查不到
好了,到這里關(guān)于 find 命令的全部?jī)?nèi)容已經(jīng)結(jié)束,希望文中的案例和總結(jié)能夠幫助你更好的使用它。同時(shí)也強(qiáng)烈建議收藏本文,以作為 Linux 常用命令手冊(cè)。
推薦閱讀:
萬(wàn)萬(wàn)沒(méi)想到,“紅孩兒”竟然做了程序員,還是CTO!
5T技術(shù)資源大放送!包括但不限于:C/C++,Linux,Python,Java,PHP,人工智能,單片機(jī),樹莓派,等等。在公眾號(hào)內(nèi)回復(fù)「1024」,即可免費(fèi)獲?。?!


