文件查找工具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
原創文章,作者:苦澀咖啡,如若轉載,請注明出處:http://www.www58058.com/36296
find命令是工作中常用的工具,同時它也是我們筆試中必考的知識點,同時find的處理動作也是至關重要的,希望能下來多多練習,熟練掌握,需要注意的是作業題要按時完成,附在總結后面。