首頁 > 軟體

Linux find命令:在目錄中查詢檔案

2020-06-16 17:14:59

find 是 Linux 中強大的搜尋命令,不僅可以按照檔名搜尋檔案,還可以按照許可權、大小、時間、inode 號等來搜尋檔案。但是 find 命令是直接在硬碟中進行搜尋的,如果指定的搜尋範圍過大,find命令就會消耗較大的系統資源,導致伺服器壓力過大。所以,在使用 find 命令搜尋時,不要指定過大的搜尋範圍。

find 命令的基本資訊如下:

  • 命令名稱:find。
  • 英文原意:search for files in a directory hierarchy.
  • 所在路徑:/bin/find。
  • 執行許可權:所有使用者。
  • 功能描述:在目錄中查詢檔案。

命令格式

[root@localhost ~]# find 搜尋路徑 [選項] 搜尋內容

find 是比較特殊的命令,它有兩個引數:

  • 第一個引數用來指定搜尋路徑;
  • 第二個引數用來指定搜尋內容。


而且find命令的選項比較複雜,我們一個一個舉例來看。

按照檔名搜尋

[root@localhost ~]#find 搜尋路徑 [選項] 搜尋內容

選項:

  • -name: 按照檔名搜尋;
  • -iname: 按照檔名搜尋,不區分檔名大小;
  • -inum: 按照 inode 號搜尋;


這是 find 最常用的用法,我們來試試:

[root@localhost ~]# find /-name yum.conf
/etc/yum.conf
#在目錄下査找檔名是yum.conf的檔案


但是 find 命令有一個小特性,就是搜尋的檔名必須和你的搜尋內容一致才能找到。如果只包含搜尋內容,則不會找到。我們做一個實驗:

[root@localhost ~]# touch yum.conf.bak
#在/root/目錄下建立一個檔案yum.conf.bak
[root@localhost ~]# find /-name yum.conf
/etc/yum.conf
#搜尋只能找到yum.conf檔案,而不能找到 yum.conf.bak 檔案

find 能夠找到的是只有和搜尋內容 yum.conf 一致的 /etc/yum.conf 檔案,而 /root/yum.conf.bak 檔案雖然含有搜尋鍵碼,但是不會被找到。這種特性我們總結為:find 命令是完全匹配的,必須和搜尋鍵碼一模一樣才會列出。

Linux 中的檔名是區分大小寫的,也就是說,搜尋小寫檔案,是找不到大寫檔案的。如果想要大小通吃,就要使用 -iname 來搜尋檔案。

[root@localhost ~]# touch CANGLS
[root@localhost ~]# touch cangls
#建立大寫和小寫檔案
[root@localhost ~]#find.-iname cangls
./CANGLS
./cangls
#使用-iname,大小寫檔案通吃

每個檔案都有 inode 號,如果我們知道 inode 號,則也可以按照 inode 號來搜尋檔案。

[root@localhost ~]#ls -i install.log
262147 install.log
#如果知道檔名,則可以用"ls -i"來査找inode號
[root@localhost ~]# find.-inum 262147
./install.log
#如果知道inode號,則可以用find命令來査找檔案

按照 inode 號搜尋檔案,也是區分硬連結檔案的重要手段,因為硬連結檔案的 inode 號是一致的。

[root@localhost ~]# ln /root/install.log /tmp/
#給install.log檔案建立一個硬連結檔案
[root@localhost ~]#ll -i /root/install.log /tmp/install.log
262147 -rw-r--r--.2 root root 24772 1 月 14 2014/root/
install.log
262147 -rw-r--r--.2 root root 24772 1 月 14 2014/tmp/
install.log
#可以看到這兩個硬連結檔案的inode號是一致的
[root@localhost ~]# find /-inum 262147
/root/install.log
/tmp/install.log
#如果硬連結不是我們自己建立的,則可以通過find命令搜尋inode號,來確定硬連結檔案

按照檔案大小搜尋

[root@localhost ~]#find 搜尋路徑 [選項] 搜尋內容

選項:

  • -size[+-]大小:按照指定大小搜尋檔案


這裡的"+"的意思是搜尋比指定大小還要大的檔案,"-" 的意思是搜尋比指定大小還要小的檔案。我們來試試:

[root@localhost ~]# ll -h install.log
-rw-r--r--.1 root root 25K 1月 14 2014 install.log #在當前目錄下有一個大小是25KB的檔案
[root@localhost ~]#
[root@localhost ~]# find.-size 25k
./install.log
#當前目錄下,査找大小剛好是25KB的檔案,可以找到
[root@localhost ~]# find .-size -25k
.
./.bashrc
./.viminfo
./.tcshrc
./.pearrc
./anaconda-ks.cfg
./test2
./.ssh
./.bash_history
./.lesshst
./.bash_profile
./yum.conf.bak
./.bashjogout
./install.log.syslog
./.cshrc
./cangls
#搜尋小於25KB的檔案,可以找到很多檔案
[root@localhost ~]# find.-size +25k
#而當前目錄下沒有大於25KB的檔案


其實 find 命令的 -size 選項是筆者個人覺得比較噁心的選項,為什麼這樣說?find 命令可以按照 KB 來搜尋,應該也可以按照 MB 來搜尋吧。

[root@localhost ~]# find.-size -25m
find:無效的-size型別"m"
#為什麼會報錯呢?其實是因為如果按照MB來搜尋,則必須是大寫的M

這就是糾結點,千位元組必須是小寫的"k",而兆位元組必領是大寫的"M"。有些人會說:"你別那麼執著啊,你就不能不寫單位,直接按照位元組搜尋啊?"很傻,很天真,不寫單位,你們就以為會按照位元組搜尋嗎?我們來試試:

[root@localhost ~]# ll anaconda-ks.cfg
-rw-------.1 root root 1207 1 月 14 2014 anaconda-ks.cfg
#anaconda-ks.cfg檔案有1207字芳
[root@localhost ~]# find.-size 1207
#但用find查詢1207,是什麼也找不到的

也就是說,find 命令的預設單位不是位元組。如果不寫單位,那麼 find 命令是按照 512 Byte 來進行査找的。 我們看看 find 命令的幫助。

[root@localhost ~]# man find
-size n[cwbkMG]
File uses n units of space. The following suffixes can be used:
'b' for 512-byte blocks (this is the default if no suffix is used)
#這是預設單位,如果單位為b或不寫單位,則按照 512Byte搜尋
'c' for bytes
#搜尋單位是c,按照位元組搜尋
'w' for two-byte words
#搜尋單位是w,按照雙位元組(中文)搜尋
'k'for Kilobytes (units of 1024 bytes)
#按照KB單位搜尋,必須是小寫的k
'M' for Megabytes (units of 1048576 bytes)
#按照MB單位搜尋,必須是大寫的M
'G' for Gigabytes (units of 1073741824 bytes)
#按照GB單位搜尋,必須是大寫的G

也就是說,如果想要按照位元組搜尋,則需要加搜尋單位"c"。我們來試試:

[root@localhost ~]# find.-size 1207c
./anaconda-ks.cfg
#使用搜尋單位c,才會按照位元組搜尋

按照修改時間搜尋

Linux 中的檔案有存取時間(atime)、資料修改時間(mtime)、狀態修改時間(ctime)這三個時間,我們也可以按照時間來搜尋檔案。

[root@localhost ~]# find搜尋路徑 [選項] 搜尋內容

選項:

  • -atime [+-]時間: 按照檔案存取時間搜尋
  • -mtime [+-]時間: 按照文改時間搜尋
  • -ctime [+-]時間: 按照檔案修改時間搜尋

這三個時間的區別我們在 stat 命令中已經解釋過了,這裡用 mtime 資料修改時間來舉例,重點說說 "[+-]"時間的含義。

  • -5:代表@內修改的檔案。
  • 5:代表前5~6天那一天修改的檔案。
  • +5:代表6天前修改的檔案。

我們畫一個時間軸,來解釋一下,如圖 1 所示。



圖 1 find時間軸


每次筆者講到這裡,"-5"代表 5 天內修改的檔案,而"+5"總有人說代表 5 天修改的檔案。要是筆者能知道 5 天系統中能建立什麼檔案,早就去買彩票了,那是未卜先知啊!所以"-5"指的是 5 天內修改的檔案,"5"指的是前 5~6 天那一天修改的檔案,"+5"指的是 6 天前修改的檔案。我們來試試:

[root@localhost ~]#find.-mtime -5
#查詢5天內修改的檔案

大家可以在系統中把幾個選項都試試,就可以明白各選項之間的差別了。

find 不僅可以按照 atmie、mtime、ctime 來査找檔案的時間,也可以按照 amin、mmin 和 cmin 來査找檔案的時間,區別只是所有 time 選項的預設單位是天,而 min 選項的預設單位是分鐘。

按照許可權搜尋

在 find 中,也可以按照檔案的許可權來進行搜尋。許可權也支援 [+/-] 選項。我們先看一下命令格式。

[root@localhost ~]# find 搜尋路徑 [選項] 搜尋內容

選項:

  • -perm 許可權模式:査找檔案許可權剛好等於"許可權模式"的檔案
  • -perm -許可權模式:査找檔案許可權全部包含"許可權模式"的檔案
  • -perm +許可權模式:査找檔案許可權包含"許可權模式"的任意一個許可權的檔案


為了便於理解,我們要舉幾個例子。先建立幾個測試檔案。

[root@localhost ~]# mkdir test
[root@localhost ~]# cd test/
[root@localhost test]# touch testl
[root@localhost test]# touch test2
[root@localhost test]# touch test3
[root@localhost test]# touch test4
#建立測試目錄,以及測試檔案
[root@localhost test]# chmod 755 testl
[root@localhost test]# chmod 444 test2
[root@localhost test]# chmod 600 test3
[root@localhost test]# chmod 200 test4
#設定實驗許可權。因為是實驗許可權,所以看起來比較彆扭
[root@localhost test]# ll
總用量0
-rwxr-xr-x 1 root root 0 6月 17 11:05 testl -r--r--r-- 1 root root 0 6月 17 11:05 test2
-rw------- 1 root root 0 6月 17 11:05 test3
-w------- 1 root root 0 6月 17 11:05 test4
#檢視許可權


【例 1】"-perm許可權模式"。
這種搜尋比較簡單,代表査找的許可權必須和指定的許可權模式一模一樣,才可以找到。

[root@localhost test]#find.-perm 444
./test2
[root@localhost test]#find.-perm 200
./test4
#按照指定許可權搜尋檔案,檔案的許可權必須和搜尋指定的許可權一致,才能找到


【例 2】"-perm-許可權模式"。
如果使用"-許可權模式",是代表的是檔案的許可權必須全部包含搜尋命令指定的許可權模式,才可以找到。

[root@localhost test]#find .-perm -200
./test4 <-此檔案許可權為200
./test3 <-此檔案許可權為600
./testl <-此檔案許可權為755
#搜尋檔案的許可權包含200的檔案,不會找到test2檔案,因為test2的許可權為444,不包含200許可權

因為 test4 的許可權 200(-w-------)、test3 的許可權 600(-rw-------)和 test1 的許可權 755(-rwxr-xr-x) 都包含 200(--w-------) 許可權,所以可以找到;而 test2 的許可權是 444 (-r--r--r--),不包含 200 (--w-------)許可權,所以找不到,再試試:

[root@localhost test]# find .-perm -444
.
./test2 <-此檔案許可權為444
./test1 <-此檔案許可權為755
#搜尋檔案的許可權包含444的檔案

上述搜尋會找到 test1 和 test2,因為 test1 的許可權 755 (-rwxr-xr-x)和 test2 的許可權 444 (-r--r--r--)都完全包含 444 (-r--r--r--)許可權,所以可以找到;而 test3 的許可權 600 (-rw-------)和 test4 的許可權 200 (-w-------)不完全包含 444 (-r--r--r--) 許可權,所以找不到。也就是說,test3 和 test4 檔案的所有者許可權雖然包含 4 許可權,但是所屬組許可權和其他人許可權都是 0,不包含 4 許可權,所以找不到,這也是完全包含的意義。

【例 3】"-perm+許可權模式"
剛剛的"-perm-許可權模式"是必須完全包含,才能找到;而"-perm+許可權模式"是只要包含任意一個指定許可權,就可以找到。我們來試試:

[root@localhost test]# find .-perm +444
./test4 <-此檔案許可權為200
./test3 <-此檔案許可權為600
./testl <-此檔案許可權為755
#搜尋檔案的許可權包含200的檔案,不會找到test2檔案,因為test2的許可權為444,不包含200許可權。

因為 test4 的許可權 200 (--w-------)、test3 的許可權 600 (-rw-------)和 test1 的許可權 755 (-rwxr-xr-x)都包含 200(--w-------)許可權,所以可以找到;而 test2 的許可權是 444 (-r--r--r--),不包含 200 (--w-------)許可權,所以找不到。

按照所有者和所屬組搜尋

[root@localhost ~]# find 搜尋路徑 [選項] 搜尋內容

選項:

  • -uid 使用者 ID:按照使用者 ID 査找所有者是指定 ID 的檔案
  • -gid 組 ID:按照使用者組 ID 査找所屬組是指定 ID 的檔案
  • -user 使用者名稱:按照使用者名稱査找所有者是指定使用者的檔案
  • -group 組名:按照組名査找所屬組是指定使用者組的檔案
  • -nouser:査找沒有所有者的檔案


這組選項比較簡單,就是按照檔案的所有者和所屬組來進行檔案的査找。在 Linux 系統中,絕大多數檔案都是使用 root 使用者身份建立的,所以在預設情況下,絕大多數系統檔案的所有者都是 root。例如:

[root@localhost ~]#find.-user root
#在當前目錄中査找所有者是 root 的檔案

由於當前目錄是 root 的家目錄,所有檔案的所有者都是 root 使用者,所以這條搜尋命令會找到當前目錄下所有的檔案。

按照所有者和所屬組搜尋時,"-nouser"選項比較常用,主要用於査找垃圾檔案。在 Linux 中,所有的檔案都有所有者,只有一種情況例外,那就是外來檔案。比如光碟和 U 盤中的檔案如果是由 Windows 複製的,在 Linux 中査看就是沒有所有者的檔案;再比如手工原始碼包安裝的檔案,也有可能沒有所有者。

除這種外來檔案外,如果系統中發現了沒有所有者的檔案,一般是沒有作用的垃圾檔案(比如使用者刪除之後遺留的檔案),這時需要使用者手工處理。搜尋沒有所有者的檔案,可以執行以下命令:

[root@localhost ~]# find/-nouser

按照檔案型別搜尋

[root@localhost ~]# find 搜尋路徑 [選項] 搜尋內容

選項:

  • -type d:查詢目錄
  • -type f:查詢普通檔案
  • -type l:查詢軟連結檔案


這個命令也很簡單,主要按照檔案型別進行搜尋。在一些特殊情況下,比如需要把普通檔案和目錄檔案區分開,比如需要把普通檔案和目錄檔案區分開,使用這個選項就很方便。

[root@localhost ~]# find /etc -type d
#查詢/etc/目錄下有哪些子目錄

邏輯運算子

[root@localhost ~]#find 搜尋路徑 [選項] 搜尋內容

選項:

  • -a:and邏輯與
  • -o:or邏輯或
  • -not:not邏輯非

1) -a:and邏輯與

find 命令也支援邏輯運算子選項,其中 -a 代表邏輯與運算,也就是 -a 的兩個條件都成立,find 搜尋的結果才成立。

舉個例子:

[root@localhost ~]# find.-size +2k -a -type f
#在當前目錄下搜尋大於2KB,並且檔案型別是普通檔案的檔案

在這個例子中,檔案既要大於 2KB,又必須是普通檔案,find 命令才可以找到。再舉個例子:

[root@localhost ~]# find.-mtime -3 -a -perm 644
#在當前目錄下搜尋3天以內修改過,並且許可權是644的檔案

2) -o:or邏輯或

-o 選項代表邏輯或運算,也就是 -o 的兩個條件只要其中一個成立,find 命令就可以找到結果。例如:

[root@localhost ~]#find.-name cangls -o -name bols
./cangls
./bols
#在當前目錄下搜尋檔名要麼是cangls的檔案,要麼是bols的檔案

-o 選項的兩個條件只要成立一個,find 命令就可以找到結果,所以這個命令既可以找到 cangls 檔案,也可以找到 bols 檔案。

3) -not:not邏輯非

-not是邏輯非,也就是取反的意思。舉個例子:
[root@localhost ~]# find.-not -name cangls
#在當前目錄下搜尋檔名不是cangls的檔案

其他選項

1) -exec選項
這裡我們主要講解兩個選項"-exec"和"-ok",這兩個選項的基本作用非常相似。我們先來看看 "exec"選項的格式。

[root@localhost ~]# find 搜尋路徑 [選項] 搜尋內容 -exec 命令2{};

首先,請大家注意這裡的"{}"和";"是標準格式,只要執行"-exec"選項,這兩個符號必須完整輸入。

其次,這個選項的作用其實是把 find 命令的結果交給由"-exec"呼叫的命令 2 來處理。"{}"就代表 find 命令的査找結果。

我們舉個例子,剛剛在講許可權的時候,使用許可權模式搜尋只能看到檔名,例如:

[root@localhost test]#find.-perm 444
./test2

如果要看檔案的具體許可權,還要用"ll"命令査看。用"-exec"選項則可以一條命令搞定:

[root@localhost test]# find.-perm 444 -exec ls -l {};
-r--r--r-- 1 root root 0 6月 17 11:05 ./test2
#使用"-exec"選項,把find命令的結果直接交給"ls -l"命令處理

"-exec"選項的作用是把 find 命令的結果放入"{}"中,再由命令 2 直接處理。在這個例子中就是用"ls -l"命令直接處理,會使 find 命令更加方便。

2) -ok選項
"-ok"選項和"-exec"選項的作用基本一致,區別在於:"-exec"的命令會直接處理,而不詢問;"-ok"的命令 2 在處理前會先詢問使用者是否這樣處理,在得到確認命令後,才會執行。例如:

[root@localhost test]# find .-perm 444 -ok rm -rf{};
< rm…./test2>?y  <-需要使用者輸入y,才會執行
#我們這次使用rm命令來刪除find找到的結果,刪除的動作最好確認一下


IT145.com E-mail:sddin#qq.com