文件查找工具locate和find的使用分析

文件查找工具locate和find的使用分析


不管是在windows系統中還是在Linux系統中,我們經常會一些文件進行搜索查找,而在Linux系統中經常用到的搜索工具有locate和find,這兩種搜索工具的工具原理和用法都不相同,一下將這對這兩種搜索工具的使用進行分析。

1、locate工具的工作原理是對/var/lib/mlocate/mlocat.db數據庫進行文件搜索,而不是實時的在磁盤上搜索,因此它具有查找速度快的特點。mlocat.db數據庫中包含所有本地文件信息,使用locate進行文件查找時主要依賴於其事先構建好的索引,其索引的構建是在系統較爲空閒時週期性的自動進行,並且索引的構建過程需要遍歷整個根文件系統,因此構建索引時的資源消耗比較大,由此可以發現locate還具有查找到的文件都是非實時文件的特點,也就是說locate查不到最近新變動過的文件,想要查找最新變動過的文件需要先使用updatedb命令手動更新數據庫。locate還具有模糊查找的特點,可以理解爲locate命令後面跟的不是文件名,而是關鍵字,關鍵字也可以使用文件通配符表示,只要符合關鍵字內容的文件都能被查找出來,另外locate搜索的不僅僅是文件名,而是全路徑。

locate的用法:locate [OPTION]... [PATTERN]...

locate常用選項如下:

-i:忽略大小寫

-n:只列出搜索到的前幾行內容

-r:支持使用正則表達式


2、find工具的工作原理與locate不同,find是實時的針對磁盤進行文件搜索的,並且find是可以對指定目錄進行精確查找的,因此find相對於locate來說查找速度較慢。find的功能非常強大,並且使用靈活。

find的用法:find [OPTION]... [查找路徑] [查找條件] [處理動作]

查找路徑:查找指定目錄下的所有文件,默認遞歸查找,如指定查找用戶家目錄下的所有文件

查找條件:根據指定的條件進行文件查找,如根據日期查找、根據文件名進行精確查找、或根據文件所屬用戶進行查找等。

處理動作:是指將查找到的文件進行怎樣的處理,如複製、刪除等,默認是-print,即列出查找到的所有文件


下面將對find工具的具體使用進行分析:


  • 查找路徑

根據指定的路徑進行文件查找,如果不指定路徑,默認情況下查找當前路徑下的所有文件

[root@liang ~]# find     或     [root@liang ~]# find ./   #兩個命令的意思是一樣的,都是查找當前目錄下的所有文件

[root@liang ~]# find /etc/      #查找/etc/目錄下的所有文件

注意:如果指定的目錄是軟鏈接,則指定該目錄時一定要在後面加上斜線,否則查找的是文件而不是目錄下的文件

[root@liang /]# ll /etc/init.d
lrwxrwxrwx. 1 root root 11 6月  15 16:47 /etc/init.d -> rc.d/init.d
[root@liang /]# find /etc/init.d 
/etc/init.d
[root@liang /]# find /etc/init.d/
/etc/init.d/
/etc/init.d/rpcidmapd
...
  • 查找條件

find命令的強大之處在於其查找條件有很多,可以根據不同的條件查找所需要的文件,並且使用非常靈活,下面將一一介紹不同的查找條件:

-name FILENAME:根據文件名精確查找文件,可以使用文件通配符

#查找當前目錄下sshd文件
[root@liang testdir]# find -name sshd 
#查找/etc 目錄下的passwd文件
[root@liang testdir]# find /etc -name passwd

-iname FILENAME:根據文件名精確查找文件,可以使用文件通配符,與-name不同的是不區分字母大小寫-

-inum NUM:按磁盤上存儲文件的inode號查找

[root@liang testdir]# find -inum 2490447

-samefile FILENAME:查找存儲在磁盤上相同inode號的文件

#查找當前目錄下與acpid相同inode號的文件
[root@liang testdir]# find -samefile acpid

-links NUM:查找軟鏈接的鏈接數爲NUM個的文件

#查找當前目錄下連接數爲10的所有文件
[root@fengl /]# find -links 10

-regex “PATTERN”:使用正則表達式查找,PATTERN匹配的是整個文件路徑字符串,而不僅僅是文件名

#查找當前目錄下所有以a或b開頭的文件,注意正則表達式一定是匹配全路徑的,當前目錄下應加上“./”
[root@liang testdir]# find -regex \./[ab].*

-user USERNAME:查找屬主爲指定用戶(UID)的文件。

-uid UserID:根據用戶UID進行查找

-group GROUPNAME:查找屬組爲指定組(GID)的文件

-gid GroupID:根據組的GID進行查找

-user與-uid其實都是根據用戶UID進行文件查找的,如果兩個用戶的UID一樣,則根據一個用戶的用戶名查找文件時會將其屬主的文件都列出來,同理,-group和-gid也是一樣的,其實都是根據組的GID進行文件查找的

#根據用戶查找
[root@liang testdir]# find /home -user ggg -ls
1703938    4 drwx------   3 liang    liang        4096 8月  3 05:29 /home/liang
1703939    4 -rw-r--r--   1 liang    liang         124 5月 11 07:21 /home/liang/.bashrc
1703940    4 drwxr-xr-x   2 liang    liang        4096 11月 12  2010 /home/liang/.gnome2
1703995    4 -rw-------   1 liang    liang         297 8月  3 05:29 /home/liang/.bash_history
1703941    4 -rw-r--r--   1 liang    liang         176 5月 11 07:21 /home/liang/.bash_profile
1703942    4 -rw-r--r--   1 liang    liang          18 5月 11 07:21 /home/liang/.bash_logout
1704026    4 drwx------   3 liang    ggg          4096 8月 17 00:50 /home/ggg
1704027    4 -rw-r--r--   1 liang    ggg           124 5月 11 07:21 /home/ggg/.bashrc
1704028    4 drwxr-xr-x   2 liang    ggg          4096 11月 12  2010 /home/ggg/.gnome2
1704029    4 -rw-r--r--   1 liang    ggg           176 5月 11 07:21 /home/ggg/.bash_profile
1704030    4 -rw-r--r--   1 liang    ggg            18 5月 11 07:21 /home/ggg/.bash_logout
#根據UID查找
[root@liang testdir]# find /home -uid 500 -ls 
1703938    4 drwx------   3 liang    liang        4096 8月  3 05:29 /home/liang
1703939    4 -rw-r--r--   1 liang    liang         124 5月 11 07:21 /home/liang/.bashrc
1703940    4 drwxr-xr-x   2 liang    liang        4096 11月 12  2010 /home/liang/.gnome2
1703995    4 -rw-------   1 liang    liang         297 8月  3 05:29 /home/liang/.bash_history
1703941    4 -rw-r--r--   1 liang    liang         176 5月 11 07:21 /home/liang/.bash_profile
1703942    4 -rw-r--r--   1 liang    liang          18 5月 11 07:21 /home/liang/.bash_logout
1704026    4 drwx------   3 liang    ggg          4096 8月 17 00:50 /home/ggg
1704027    4 -rw-r--r--   1 liang    ggg           124 5月 11 07:21 /home/ggg/.bashrc
1704028    4 drwxr-xr-x   2 liang    ggg          4096 11月 12  2010 /home/ggg/.gnome2
1704029    4 -rw-r--r--   1 liang    ggg           176 5月 11 07:21 /home/ggg/.bash_profile
1704030    4 -rw-r--r--   1 liang    ggg            18 5月 11 07:21 /home/ggg/.bash_logout
#根據用戶組名查找
[root@liang testdir]# find /home -group feng -ls 
1703943    4 drwx------   3 feng     feng         4096 8月  3 02:16 /home/feng
1703944    4 -rw-r--r--   1 feng     feng          124 5月 11 07:21 /home/feng/.bashrc
1703945    4 drwxr-xr-x   2 feng     feng         4096 11月 12  2010 /home/feng/.gnome2
1703946    4 -rw-r--r--   1 feng     feng          176 5月 11 07:21 /home/feng/.bash_profile
1703947    4 -rw-r--r--   1 feng     feng           18 5月 11 07:21 /home/feng/.bash_logout
#根據用戶組的GID查找
[root@liang testdir]# find /home -gid 501 -ls 
1703943    4 drwx------   3 feng     feng         4096 8月  3 02:16 /home/feng
1703944    4 -rw-r--r--   1 feng     feng          124 5月 11 07:21 /home/feng/.bashrc
1703945    4 drwxr-xr-x   2 feng     feng         4096 11月 12  2010 /home/feng/.gnome2
1703946    4 -rw-r--r--   1 feng     feng          176 5月 11 07:21 /home/feng/.bash_profile
1703947    4 -rw-r--r--   1 feng     feng           18 5月 11 07:21 /home/feng/.bash_logout

-nouser:查找沒有屬主的文件

-nogroup:查找沒有屬組的文件

#查找/home/目錄下沒有屬組的所有文件
[root@liang liang]# find /home -nogroup -ls
1704026    4 drwx------   3 ggg      4334         4096 8月 17 00:50 /home/ggg
1704027    4 -rw-r--r--   1 ggg      4334          124 5月 11 07:21 /home/ggg/.bashrc
1704028    4 drwxr-xr-x   2 ggg      4334         4096 11月 12  2010 /home/ggg/.gnome2
1704029    4 -rw-r--r--   1 ggg      4334          176 5月 11 07:21 /home/ggg/.bash_profile
1704030    4 -rw-r--r--   1 ggg      4334           18 5月 11 07:21 /home/ggg/.bash_logout
#查找/home/目錄下沒有屬主的所有文件
[root@liang liang]# find /home -nouser -ls
2097156    4 drwx------   3 4321     root         4096 8月  3 04:10 /home/test
2097157    4 -rw-r--r--   1 4321     root          124 5月 11 07:21 /home/test/.bashrc
2097158    4 drwxr-xr-x   2 4321     root         4096 11月 12  2010 /home/test/.gnome2
2097159    4 -rw-r--r--   1 4321     root          176 5月 11 07:21 /home/test/.bash_profile
2097160    4 -rw-r--r--   1 4321     root           18 5月 11 07:21 /home/test/.bash_logout

-type TYPE:根據文件類型進行查找,文件類型包括以下幾種:

f:普通文件

d:目錄文件

l:符號鏈接文件

s:套接字文件

b:塊設備文件

c:字符設備文件

p:管道文件

#查找/home目錄下的所有普通文件
[root@liang liang]# find /home -type f
#查找/home目錄下的所有目錄文件
[root@liang liang]# find /home -type d

-size [+|-]#UNIT:“#”代表數字,按照文件大小來查找,UNIT代表單位,常用單位有k、M、G

#UNIT表示的範圍是:(#-1,#]

-#UNIT表示的範圍是:[0,#-1]

+#UNIT表示的範圍是:(#,∞)

#查找/usr目錄下大小爲10M的文件,其實查到的是9-10M之間的文件
[root@liang liang]# find /usr -size 10M
#查找/usr目錄下大於10M的文件
[root@liang liang]# find /usr -size +10M
#查找/usr目錄下小於等於10M的文件
[root@liang liang]# find /usr -size -11M

以下“#”表示數字

-atime [+|-]#:根據訪問時間戳查找,以“天”爲單位

-amin [+|-]#:根據訪問時間戳查找,以“分鐘”爲單位

-mtime [+|-]#:根據修改時間戳查找,以“天”爲單位

-mmin [+|-]#:根據修改時間戳查找,以“分鐘”爲單位

-ctime [+|-]#:根據狀態變更時間戳查找,以“天”爲單位

-cmin [+|-]#:根據狀態變更時間戳查找,以“分鐘”爲單位

#表示的範圍是:[#,#-1)

-#表示的範圍是:[0,#)

+#表示的範圍是:[#+1,∞]

#查找/home目錄下前3分鐘時訪問的文件,實際查找的是前2-3分鐘之間訪問的文件
[root@liang liang]# find /home -amin 3 
#查找/home目錄下3分鐘內訪問的文件
[root@liang liang]# find /home -amin -3
#查找/home目錄下3分鐘前訪問的文件
[root@liang liang]# find /home -amin +2

-perm  MODE:根據權限進行文件查找,精確匹配權限

-perm -MODE:根據權限進行文件查找,每一類(u,g,o)對象都必須同時擁有指定的權限,“與”關係。如-222表示對應的u、g、o三者都有寫權限的文件。0表示不關注,如-220表示對應的u、g兩者都有寫權限的文件。

-perm /MODE:centos7之前的版本還可以用-perm +MODE表示,也是根據權限進行文件查找,任何一類(u,g,o)對象中只要有一位匹配即可,或關係。如/222表示對應的u,g,o三者中任何一個有寫權限的文件。

#查找/etc/目錄下權限爲644的所有文件
[root@liang liang]# find /etc/ -perm 644
#查找/etc/目錄下任何一類用戶有執行權限的所有文件
[root@liang liang]# find /etc/ -perm /111
#查找/etc/目錄下所有用戶都有執行權限的所有文件
[root@liang liang]# find /etc/ -perm -111 
#查找/etc/目錄下其他用戶有執行權限的所有文件
[root@liang liang]# find /etc/ -perm -001
  • 處理動作

-print:find命令默認的處理動作,將查找到的文件顯示至屏幕上

-ls:類似與對查找到的文件執行“ls -l”命令

#查找當前目錄下名爲network的文件,使用默認動作處理查找到的文件
[root@liang7 etc]# find -name network
./sysconfig/network
./rc.d/init.d/network
./vmware-tools/scripts/vmware/network
#查找當前目錄下名爲network的文件,使用-print選項處理查找到的問及那
[root@liang7 etc]# find -name network -print
./sysconfig/network
./rc.d/init.d/network
./vmware-tools/scripts/vmware/network
#查找當前目錄下名爲network的文件,使用-ls選項處理查找到的文件
[root@liang7 etc]# find -name network -ls
137432923    4 -rw-r--r--   1 root     root           22 Jul 21 02:52 ./sysconfig/network
939715    8 -rwxr-xr-x   1 root     root         6630 Sep 16  2015 ./rc.d/init.d/network
269689071   16 -rwxr-xr-x   1 root     root        14638 Nov 21  2015 ./vmware-tools/scripts/vmware/network

-delete:刪除查找到的文件全部刪除(此選項不做演示)

-fls file:將查找到的所有文件的長格式信息保存至指定文件中

#查找當前目錄下名爲network的文件,使用-fls選項將查找到的文件的長格式結果保存在find.log文件中
[root@liang7 etc]# find -name network -fls find.log
#查看保存到find.log文件中的結果
[root@liang7 etc]# cat find.log 
137432923    4 -rw-r--r--   1 root     root           22 Jul 21 02:52 ./sysconfig/network
939715    8 -rwxr-xr-x   1 root     root         6630 Sep 16  2015 ./rc.d/init.d/network
269689071   16 -rwxr-xr-x   1 root     root        14638 Nov 21  2015 ./vmware-tools/scripts/vmware/network

-ok CMMAND {} \;:對查找到的每個文件執行由COMMAND指定的命令,並且對於每個文件執行命令前都會交互式的要求用戶確認

-exec CMMAND {} \;:對查找到的每個文件執行由COMMAND指定的命令,與-ok不同的是沒有交互式提醒,直接進行CMMAND的操作,不需要用戶確認

#使用-exec選項進行備份,要求以“.orig”作爲擴展名備份當前目錄下以“.conf”結尾的配置文件
[root@liang7 testdir]# find -name "*\.conf" -exec cp {} {}.orig \;
#查看備份後的文件
[root@liang7 testdir]# find -name "*.orig"
./fonts/conf.d/66-sil-abyssinica.conf.orig
./fonts/conf.d/59-liberation-mono.conf.orig
./fonts/conf.d/65-0-lohit-tamil.conf.orig
...
#提示修改當前目錄下其他用戶具有寫權限的普通文件
[root@liang7 testdir]# find -type f -perm -002 -ok chmod o-w {} \;
< chmod ... ./yum.conf > ? y
#查看修改權限後的文件
[root@liang7 testdir]# find -name yum.conf -ls
   774    4 -rw-rw-r--   1 root     root          970 Aug 16 22:18 ./yum.conf

以上命令中用到的“{}”的作用是引用find查找到的文件名稱自身,但是有時候查找到的文件有很多,將會超出後面命令的參數範圍,這時後面的命令執行時將會提示錯誤,這種情況下可以使用xargs命令規避此問題。

find | xargs CMMAND

#查找當前目錄下所有以“.orig”結尾的文件並刪除
[root@liang7 testdir]# find -name "*.orig" | xargs rm
#查看刪除結果
[root@liang7 testdir]# find -name "*.orig" | wc -l
0


  • 查找條件之間的邏輯關係

find命令可以同時跟多個查找條件,默認情況下多個查找條件之間的關係是“與”關係。多個查找條件之間的關係有如下幾種:

-a:“與”關係,比如查找/etc目錄下屬主爲test用戶並且具有執行權限的文件,這時兩多個查找條件之間需要使用-a選項,默認情況下就是-a;

#默認情況下的寫法
[root@liang7 testdir]# find /etc -user test -perm /100
#使用-a選項的寫法
[root@liang7 testdir]# find /etc -user test -a -perm /100

-o:“或”關係,比如查找當前目錄下以 “.sh”結尾的文件或查找以“.conf”f結尾的文件,這時兩個查找條件之間需要使用-o選項;

#使用-o選項的寫法
[root@liang7 testdir]# find -name "*.sh" -o -name "*.conf"

-not或 !:“非”選項,比如查找當前目錄下除了test用戶外的所有文件,這時指定用戶的條件參數前需要使用-not選項;

#使用-not選項的寫法
[root@liang7 testdir]# find -not -user test
#使用!的寫法
[root@liang7 testdir]# find ! -user test

-a,-o,-not三個選項同時使用時,也是有優先級之分的。

-a的優先級要高於-o的優先級,如果查找條件中同時出現-a和-o選項,則先執行-a後執行-o,如:A  -o B  C,其執行的結果是滿足條件A或滿足條件BC,如果想實現滿足條件A或B,且滿足條件C,需要使用小括號將A或B括起來,如(A -o B) C 。

#查找當前系統上沒有屬主或屬組,且最近一週沒有被訪問過的文件
[root@liang7 testdir]# find / \( -nouser -o -nogroup \) -atime -7

當使用-not選項且將多個查找條件用小括號括起來是需要注意德·摩根定律,該定律的表示方法如下:

(非P)或(非Q)=非(P 且 Q)即(! P)-o (! Q)=! (P -a Q)

(非P)且(非Q)=非(P 或 Q)即(! P)-a (! Q)=! (P -o Q)

#查找/var目錄下不屬於root、lp、gdm的所有文件(帶有小括號的寫法)
[root@liang7 testdir]# find /var -not \( -user root -o -user lp -o -user gdm \)
#查找/var目錄下不屬於root、lp、gdm的所有文件(不使用小括號的寫法)
[root@liang7 testdir]# find /var -not -user root -not -user lp -not -user gdm 
#查找/var目錄下最近一週內其內容修改過,同時屬主不爲root,也不是postfix的文件(帶有小括號的寫法)
[root@liang7 testdir]# find /var -mtime -7 -not \( -user root -o -user postfix \)
#查找/var目錄下最近一週內其內容修改過,同時屬主不爲root,也不是postfix的文件(不使用小括號的寫法)
[root@liang7 testdir]# find /var -mtime -7 -not -user root -not -user postfix


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章