Linux 文件搜索神器 find 實戰詳解


大家好,我是肖邦,這是我的第 10 篇原創文章。

在 Linux 系統使用中,作為一個管理員,我希望能查找系統中所有的大小超過 200M 文件,查看近 7 天系統中哪些文件被修改過,找出所有子目錄中的可執行文件,這些任務需求 find 命令都可以輕松勝任。

在 Linux 系統文件中常用的屬性可以分為以下內容:名稱、大小、權限、屬主、修改時間、訪問時間等,find 命令可以按照指定的屬性為條件進行查找。

廢話不多,直接開干,下邊進入案例實戰。

案例實戰

(一)按文件名稱查找

按照文件名稱查找是 find 最常見的用法,需要注意的是,搜索的文件名必須完全匹配,才能找到對應的文件。

1. 查找當前目錄下所有 go 文件

$ find . -name "*.go"

2. 在 etc 目錄下,查找大寫字母開頭的 txt 文件

$ find /etc -name "[A-Z]*.txt" -print

3. 在當前目錄下查找不是 out 開頭的 txt 文件

$ find . -name "out*" -prune -o -name "*.txt" -print

4. 在當前目錄除 git 子目錄外查找 txt 文件

$ find . -path "./git" -prune -o -name "*.txt" -print

5. 找出某個文件的所有硬鏈接,ls 命令 -i 選項可以查看文件的 inode 號

$ ls -i 1.txt
138956 1.txt
$ find . -num 138956

這里補充一個小技巧,搜索文件時使用 -iname 參數可以忽略文件名稱大小寫

(二)按文件類型查找

1. 在當前目錄下,查找軟連接文件

$ find . -type l -print

2. 在當前目錄下,查找 log 結尾的普通文件,f 表示普通文件類型

$ find . -type f -name "*.log"

(三)按文件大小查找

1. 查找小於 64k 的文件

$ find . -size -64k -print

2. 查找大小超過 200M 的文件

$ find . -size +200M -type f -print

(四)按時間查找

1. 查找 2 天內被修改過的文件

$ find . -mtime -2 -type f -print

2. 查找 2 天前被更改過的文件,-mtime 表示內容修改時間

$ find . -mtime +2 -type f -print

3. 查找一天內被訪問的文件,-atime 表示訪問時間

$ find . -atime -1 -type f -print

4. 查找一天內狀態被改變的文件,-ctime 表示元數據被變化時間

$ find . -ctime -1 -type f -print

5. 查找比 chopin.txt 新的文件

$ find . -newer "chopin.txt" -type f -print
$ find . ! -newer "chopin.txt" -type f -print # 舊

(五)根據權限查找

1. 查找當前目錄權限為 644 的文件

$ find . -type f -perm 644

2. 查找 etc 目錄下至少有一個用戶有寫權限的文件

$ find /etc -type f -perm /222

3. 查找 etc 目錄下所有用戶都有執行權限的文件

$ find /etc -perm -111 -ls

(六)組合條件

1. 查找當前目錄下屬於 chopin 用戶的普通文件,-a 可以省略

$ find . -type f -a -user chopin -print

2. 查找當前目錄下大於 2M 或 2 天前被修過的文件

$ find . -size +2M -o -mtime +2 -print

3. 查找當前目錄下不是普通文件

$ find . -not -type f
$ find . ! -type f

4. 查找非空文件

$ find . ! -empty

(七)處理動作

find 根據上述各種條件查找后,支持執行相關的處理動作,可以讓我們的更方便和靈活,而不只是打印出來

1. -print 默認為打印,可省略

$ find . -name "*.log" -print
$ find . -name "*.log" # 等價

2. -ls 以 ls 長文件的格式形式輸出

$ 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 命令,同理我們可以傳遞給任何一個 Linux 命令,功能十分強大,也很靈活。

$ 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 功能一樣,只是操作時會提示用戶確認,僅此而已。當然,在生產環境上,我們還是推薦使用 ok

(八)經典案例

如果存在一個名稱亂碼的文件,想要刪除它,該怎么辦?即使我們復制亂碼名稱到命令行,很有可能終端不能正確識別。不用擔心,下邊來展示下 find 是如何優雅的解決問題的。

$ ls  -i
138957 a.txt  138959 T.txt  132395 ڹ��.txt

$ find . -inum 132395 -exec rm {} \;

命令中,-inum 指定的是文件的 inode 號,它是系統中每個文件對應的唯一編號,find 通過編號找到后,執行刪除操作。

總結歸納

find 命令是 Linux 命令中最有用的命令之一,它的功能非常強大,且語法復雜。其實我們不一定需要了解它的所有細節,掌握上述實戰案例中的常見用法,足夠滿足日常工作中的大部分需求。

下邊我們一起來總結下 find 命令常見用法,加深對 find 使用方法的理解。

命令格式

find path -option [-exec ...]

按文件名查找

  • -name:按照文件名稱查找,准確匹配;
  • -iname:不區分文件名的大小寫;
  • -inode:按照文件 inode 號查找;

按照文件類型查找

按照文件類型查找,可以使用 -type 選項,具體支持的文件類型如下:

  • f:普通文件
  • d:目錄文件
  • l:鏈接文件
  • s:套接字文件
  • p:管道文件
  • b:塊設備文件,比如:磁盤
  • c:字符設備文件,比如:鍵盤、鼠標、網卡

按照文件從屬關系查找

  • -user:以用戶名查找
  • -group:以組名查找
  • -uid:以用戶 ID 查找
  • -gid:以組 ID 查找
  • -nouser:查找沒有屬主的文件
  • -nogroup:查找沒有屬組的文件

按照文件大小查找

按照文件大小查找功能十分常用,用 -size 選項,選項后邊指定大小 1024M,表示大小的格式有如下幾種:

  • -5M:查找小於 5M 的文件
  • +5M:查找大於 5M 的文件
  • 5M:查找大小為 5M 的文件

單位支持的有 c(字節)kMG 等,需要注意的是默認單位並不是字節,而是 b,大小為 512 字節。

按照時間查找

按照時間查找的功能對系統管理員來說,十分常用,find 支持如下幾種時間類型:

  • atime:以訪問時間查找
  • mtime:以數據修改時間查找
  • ctime:以元數據修改時間查找
  • newer:以文件為條件,判斷比它新的文件

按時間查找時,使用格式如下:

  • -atime -5:表示 5 天內訪問過的文件;
  • -atime +5:表示 6 天前訪問過的文件;
  • -atime 5:表示前 5-6 那一天訪問的文件;

這個 +5 含義總是被人理解錯,誤認為是 5 天后修改的文件,如果能知道未來 5 天的事情,小編早就去買彩票了!可能這么說還不是很清楚,直接看圖吧!

find 不僅可以按 為單位來查找文件,可以按照 aminmmincmin 來查找,區別只是 min 選項單位為分鍾。

按照權限查找

按權限查找是通過 -perm 選項,可以按照如下方式使用:

  • -perm 644:精確權限查找
  • -perm /666:任何一類用戶中的任何一位符合條件即滿足
  • -perm -222:每一類用戶的每一位同時符合條件即滿足

組合條件

find 可以使用多個條件的組合,支持 -a-o-not!,比較簡單,不再詳細描述其含義。

處理動作

find 根據各種條件查找后,支持執行相關的處理動作,可以讓我們的更方便和靈活,而不只是打印出來。

  • -print:打印,默認動作,可省略
  • -ls:以 ls 長文件格式輸出
  • -delete:刪除查找到的文件
  • -exec:查找到的文件傳遞給任何 Linux 命令
  • -ok:與 exec 功能相同,區別是需要用戶確認每次的操作

再啰嗦一下,find 命令支持的參數和選項比較多,文中只是總結出最常用、核心的參數選項。如果上述命令確實不滿足需求,可以請教你的男人 man find

這里需要提一下,find 搜索文件時通過掃描磁盤來進行的,盡可能不要大范圍的搜索文件,尤其是在 / 目錄下搜索,會長時間消耗服務器的 cpu 資源。如果是生產環境的機器,執行前要考慮是否會對業務造成影響。

擴展 locate

雖然 find 功能非常強大,但要知道的是,find 執行過程是通過掃描磁盤文件來進行查找的,如果大范圍的查找文件,需要花費的時間很長,且消耗服務器 cpu 資源。

這里推薦另一個 Linux 文件查找神器 locate,類似於 win 平台下的 everything。它基於索引表進行查詢,查詢速度非常快,基本不占用 cpu 資源。

使用方法非常簡單

$ locate file.txt
$ locate /etc/httpd

需要注意,如果是當天新創建的文件,通過 locate 默認是查不到的,因為它的數據庫默認是每天自動更新一次。如果希望查詢到當天創建的新文件,需要執行 updatedb 即可。

查找速度快是 locate 的優勢,但它的缺點也非常明顯:

  • 模糊查詢
  • 查找匹配模式單一
  • 查詢的名稱匹配路徑命令
  • 索引表的建立會占用磁盤空間
  • 非實時查詢,當天數據可能查不到

好了,到這里關於 find 命令的全部內容已經結束,希望文中的案例和總結能夠幫助你更好的使用它。同時也強烈建議收藏本文,以作為 Linux 常用命令手冊。

好了,本次分享就到這里了!謝謝大家,我是肖邦,歡迎關注后續的精彩內容。

 

出處:https://www.cnblogs.com/liwei0526vip/p/14354590.html

=======================================================================================

Linux中15個Find命令示例

基於訪問/修改/更改時間查找文件

你可以找到基於以下三個文件的時間屬性的文件。

  1. 訪問時間的文件。文件訪問時,訪問時間得到更新。
  2. 的文件的修改時間文件內容修改時,修改時間得到更新。
  3. 更改文件的時間。更改時間時,被更新的inode數據的變化

在下面的例子中,min選項之間的差異和時間選項是參數。

  • 分論點將它的參數為分鍾。例如,60分鍾(1小時)= 60分鍾。
  • 時間參數,將它的參數為24小時。例如,時間2 = 2 * 24小時(2天)。
  • 雖然這樣做的24個小時計算,小數部分都將被忽略,所以25小時為24小時,和47小時取為24小時,僅48小時為48小時。要獲得更清晰的參考atime的部分find命令的手冊頁。

例1:找到在1個小時內被更改的文件

想要通過文件修改時間找出文件,可以使用參數 -mmin -mtime。下面是man手冊中有關mmin和mtime的定義。

  • -mmin n 文件最后一次修改是在n分鍾之內
  • -mtime n 文件最后一次修改是在 n*24小時之內(譯者注:也就是n天了唄)

執行下面例子中的命令,將會找到當前目錄以及其子目錄下,最近一次修改時間在1個小時(60分鍾)之內的文件或目錄

1 # find . -mmin -60

同樣的方式,執行下面例子中的命令,將會找到24小時(1天)內修改了的文件(文件系統根目錄 / 下)

1 # find / -mtime -1

例2:找到1個小時內被訪問過的文件

想要通過文件訪問時間找出文件,可以使用參數 -amin -atime。下面是man手冊中有關amin和atime的定義。

  • -amin n 文件最后一次訪問是在n分鍾之內
  • -atime n 文件最后一次訪問是在 n*24小時之內

執行下面例子中的命令,將會找到當前目錄以及其子目錄下,最近一次訪問時間在1個小時(60分鍾)之內的文件或目錄

1 # find . -amin -60

同樣的方式,執行下面例子中的命令,將會找到24小時(1天)內被訪問了的文件(文件系統根目錄 / 下)

1 # find / -atime -1

例3:查找一個小時內狀態被改變的文件

(譯者注:這里的改變更第1個例子的更改文件內容時間是不同概念,這里是更改的是文件inode的數據,比如文件的權限,所屬人等等信息)

要查找文件的inode的更改時間,使用-cmin和-ctime選項

  • -cmin n  文件的狀態在n分鍾內被改變
  • -ctime n  文件狀態在n*24小時內(也就是n天內)被改變

(譯者注:如果上面的n為-n形式,則表示n分鍾/天之內,n為+n則表示n分鍾/天之前)

下面的例子在當前目錄和其子目錄下面查找一個小時內文件狀態改變的文件(也就是60分鍾內):

1 # find . -cmin -60

同樣的道理,下面的例子在根目錄/及其子目錄下一天內(24小時內)文件狀態被改變的文件列表:

1 # find / -ctime -1

例4:搜索僅僅限定於文件,不顯示文件夾

上面的例子搜索出來不僅僅有文件,還會顯示文件夾。因為當一個文件被訪問的時候,它所處的文件夾也會被訪問,如果你對文件夾不感興趣,那么可以使用 -type f 選項

下面的例子會顯示30分鍾內被修改過的文件,文件夾不顯示:

01 # find /etc/sysconfig -amin -30
02 .
03 ./console
04 ./network-scripts
05 ./i18n
06 ./rhn
07 ./rhn/clientCaps.d
08 ./networking
09 ./networking/profiles
10 ./networking/profiles/default
11 ./networking/profiles/default/resolv.conf
12 ./networking/profiles/default/hosts
13 ./networking/devices
14 ./apm-scripts
15 [注: 上面的輸出包含了文件和文件夾]
16  
17 # find /etc/sysconfig -amin -30 -type f
18 ./i18n
19 ./networking/profiles/default/resolv.conf
20 ./networking/profiles/default/hosts
21 [注: 上面的輸出僅僅包含文件]

 

例5: 僅僅查找非隱藏的文件(不顯示隱藏文件):

如果我們查找的時候不想隱藏文件也顯示出來,可以使用下面的正則式查找:

下面的命令會顯示當前目錄及其子目錄下15分鍾內文件內容被修改過的文件,並且只列出非隱藏文件。也就是說,以.開頭的文件時不會顯示出來的

1 # find . -mmin -15 \( ! -regex ".*/\..*" \)

基於文件比較的查找命令

我們平時通過更別的東西進行比較,會更容易記住一些事情。比如說我想找出在我編輯test文件之后編輯過的文件。你可以通過test這個文件的編輯時間作為比較基准去查找之后編輯過的文件:

例6: 查找文件修改時間在某一文件修改后的文件:

1 語法: find -newer FILE

下面的例子顯示在/etc/passwd修改之后被修改過的文件。對於系統管理員,想知道你新增了一個用戶后去跟蹤系統的活動狀態是很有幫助的(萬一那新用戶不老實,一上來就亂搞,你很快就知道了  ^_^):

1 # find -newer /etc/passwd

例7:查找文件訪問時間在某一文件的修改時間之后的文件:

1 # find -newer /etc/passwd

下面的例子顯示所有在/etc/hosts文件被修改后被訪問到的文件。如果你新增了一個主機/端口記錄在/etc/hosts文件中,你很可能很想知道在那之后有什么文件被訪問到了,下面是這個命令:

1 # find -anewer /etc/hosts

例8:查找狀態改變時間在某個文件修改時間之后的文件:

1 語法: find -cnewer FILE

下面的例子顯示在修改文件/etc/fstab之后所有文件狀態改變過的文件。如果你在/etc/fstab新增了一個掛載點,你很可能想知道之后哪些文件的狀態發生了改變,這時候你可以使用如下命令:

1 # find -cnewer /etc/fstab

在查找到的文件列表結果上直接執行命令:

這之前你已經看到了如果通過find命令去查找各種條件的文件列表。如果你對這些find命令還不熟悉,我建議你看完上面的第一部分

接下來這部分我們向你介紹如果在find命令上執行各種不同的命令,也就是說如何去操作find命令查找出來的文件列表。

我們能在find命令查找出來的文件名列表上指定任意的操作:

1 # find <CONDITION to Find files> -exec <OPERATION> \;

其中的OPERATION可以是任意的命令,下面列舉一下比較常用的:

  •  rm 命令,用於刪除find查找出來的文件
  •  mv 命令,用於重命名查找出的文件
  •  ls -l 命令,顯示查找出的文件的詳細信息
  •  md5sum, 對查找出的文件進行md5sum運算,可以獲得一個字符串,用於檢測文件內容的合法性
  •  wc 命令,用於統計計算文件的單詞數量,文件大小等待
  •  執行任何Unix的shell命令
  •  執行你自己寫的shell腳本,參數就是每個查找出來的文件名

例9:在find命令輸出上使用 ls -l, 列舉出1小時內被編輯過的文件的詳細信息

1 # find -mmin -60
2 ./cron
3 ./secure
4  
5 # find -mmin -60 -exec ls -l {} \;
6 -rw-------  1 root root 1028 Jun 21 15:01 ./cron
7 -rw-------  1 root root 831752 Jun 21 15:42 ./secure

例10:僅僅在當前文件系統中搜索

系統管理員有時候僅僅想在/掛載的文件系統分區上搜索,而不想去搜索其他的掛載分區,比如/home/掛載分區。如果你有多個分區被掛載了,你想在/下搜索,一般可以按下面的這樣做

下面這個命令會搜索根目錄/及其子目錄下所有.log結尾的文件名。如果你有多個分區在/下面,那么這個搜索會去搜索所有的被掛載的分區:

1 # find / -name "*.log"

如果我們使用-xdev選項,那么僅僅會在在當前文件系統中搜索,下面是在xdev的man page上面找到的一段-xdev的定義:

  • -xdev Don’t descend directories on other filesystems.

下面的命令會在/目錄及其子目錄下搜索當前文件系統(也就是/掛載的文件系統)中所有以.log結尾的文件,也就是說如果你有多個分區掛載在/下面,下面的搜索不會去搜索其他的分區的(比如/home/)

1 # find / -xdev -name "*.log"

例11: 在同一個命令中使用多個{}

linux手冊說命令中只能使用一個{},不過你可以像下面這樣在同一個命令中使用多個{}

1 # find -name "*.txt" cp {} {}.bkup \;

注意,在同一個命令中使用這個{}是可以的,但是在不同的命令里就不行了,也就是說,如果你想象下面這樣重命名文件是行不通的

1 find -name "*.txt" -exec mv {} `basename {} .htm`.html \;

例12: 使用多個{}實例

你可以像下面這樣寫一個shell腳本去模擬上面那個重命名的例子

1 # mv "$1" "`basename "$1" .htm`.html"

上面的雙引號是為了防止文件名中出現的空格,不加的話會有問題。然后你把這個shell腳本保存為mv.sh,你可以像下面這樣使用find命令了

1 find -name "*.html" -exec ./mv.sh '{}' \;

所以,任何情況下你在find命令執行中想使用同一個文件名多次的話,先寫一個腳本,然后在find中通過-exec執行這個腳本,把文件名參數傳遞進去就行,這是最簡單的辦法

例13: 將錯誤重定向到/dev/nul

重定向錯誤輸出一般不是什么好的想法。一個有經驗的程序員懂得在終端顯示錯誤並及時修正它是很重要的。

尤其是在find命令中重定向錯誤不是個好的實踐。 但是如果你確實不想看到那些煩人的錯誤,想把錯誤都重定向到null設備中(也就是linux上的黑洞裝置,任何丟進去的東西消失的無影無蹤了)。你可以像下面這樣做

1 find -name "*.txt" 2>>/dev/null

有時候這是很有用的。比如,如果你想通過你自己的賬號在/目錄下查找所有的*.conf文件,你會得到很多很多的"Permission denied"的錯誤消息, 就像下面這樣:

01 find / -name "*.conf"
02 /sbin/generate-modprobe.conf
03 find: /tmp/orbit-root: Permission denied
04 find: /tmp/ssh-gccBMp5019: Permission denied
05 find: /tmp/keyring-5iqiGo: Permission denied
06 find: /var/log/httpd: Permission denied
07 find: /var/log/ppp: Permission denied
08 /boot/grub/grub.conf
09 find: /var/log/audit: Permission denied
10 find: /var/log/squid: Permission denied
11 find: /var/log/samba: Permission denied
12 find: /var/cache/alchemist/printconf.rpm/wm: Permission denied
13 [Note: There are two valid *.conf files burned in the "Permission denied" messages]

你說煩人不?所以,如果你只想看到find命令真實的查找結果而不是這些"Permission denied"錯誤消息,你可以將這些錯誤消息重定向到/dev/null中去

1 find / -name "*.conf" 2>>/dev/null
2 /sbin/generate-modprobe.conf
3 /boot/grub/grub.conf
4 [Note: All the "Permission denied" messages are not displayed]

例14: 將文件名中的空格換成下划線

你從網上下載下來的音頻文件的文件名很多都帶有空格。但是帶有空格的文件名在linux(類Unix)系統里面是很不好的。你可以使用find然后后面加上rename命令的替換功能去重命名這些文件,將空格轉換成下划線

下面顯示怎樣將所有mp3文件的文件名中的空格換成_

1 find . -type f -iname “*.mp3″ -exec rename “s/ /_/g” {} \;

例15: 在find結果中同時執行兩條命令

在find的man page頁面中,下面是一次文件查找遍歷中使用兩條命令的語法舉例

下面的find命令的例子,遍歷文件系統一次,列出擁有setuid屬性的文件和目錄,寫入/root/suid.txt文件, 如果文件大小超過100M,將其記錄到/root/big.txt中

 

1 # find / \( -perm -4000 -fprintf /root/suid.txt '%#m %u %p\n' \) , \
2  \( -size +100M -fprintf /root/big.txt '%-10s %p\n' \)

 

出處:https://www.cnblogs.com/weifeng1463/p/9429856.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM