Linux基礎之文件查找工具:locate、find

引言

在學習Linux中的文件查找時,突然聯想到平時用的搜索引擎,在生活中我們想獲取什麼信息,在google等搜索引擎裏面敲入就能列出符合我們條件的相關信息。如果我們不滿意搜索結果可以進一步精確我們想查找內容的搜索內容,這在Linux的文件查找中稱爲精確匹配,但是如果我們雖然知道我們想要的內容,但是找不到特別精確的言辭來形容它因此只能輸入描述性內容爲搜索條件,這種在Linux的文件查找中可以稱爲模糊匹配。本文的初衷是希望這篇文章可以解決大家在使用Linux的過程中不至於因爲查找某個文件找不到而抓狂。

                                                                    實驗環境CentOS7.2



Linux查找工具

Linux中的查找工具有兩個:locatefind

locate:非實時查找,根據索引查找

find:實時查找,遍歷所有文件進行條件匹配




locate

locate屬於非實時查找,它根據事先構建的索引數據庫,匹配文件信息進而定位符合條件的文件。

其需事先構建的索引數據庫在/var/lib/mlocate/mlocate.db,索引的構建過程需要遍歷整個根文件系統,極其耗費資源,因此其常常在系統較爲空閒時進行(通常設置自動執行),也可以進行手動更新數據庫命令爲:updatedb

locate的工作特性:查找速度快模糊查找非實時查找

命令使用格式

  locate [option]...PATTEN...

    -b:只匹配路徑中的基名

    -c:統計出共有多少個符合條件的文件

    -r:BRE(基本正則表達式)

[root@localhost etc]# locate -c file
2540
[root@localhost etc]# locate -b pwd
/etc/.pwd.lock
/usr/bin/pwd
/usr/bin/pwdx
/usr/lib/modules/3.10.0-327.el7.x86_64/kernel/drivers/watchdog/hpwdt.ko
/usr/lib64/cracklib_dict.pwd
/usr/lib64/python2.7/lib-dynload/spwdmodule.so
/usr/sbin/unix_chkpwd
/usr/share/cracklib/cracklib-small.pwd
/usr/share/cracklib/pw_dict.pwd
/usr/share/man/man0p/pwd.h.0p.gz
/usr/share/man/man1/pwd.1.gz
/usr/share/man/man1/pwdx.1.gz
/usr/share/man/man1p/pwd.1p.gz
/usr/share/man/man3/lckpwdf.3.gz
/usr/share/man/man3/ulckpwdf.3.gz
/usr/share/man/man8/unix_chkpwd.8.gz
/usr/share/man/overrides/de/man1/pwdx.1
/usr/share/man/overrides/fr/man1/pwdx.1
/usr/share/man/overrides/uk/man1/pwdx.1
[root@localhost test]# locate -r '.*scrip2$' 
/test/scrip2
[root@localhost test]#

上面演示了locate的三種選項的簡單用法




find

find屬於實時查找工具,通過遍歷指定起始路徑下文件系統層級結構完成文件查找。

它的工作特性:查找速度略慢、精確查找、實時查找。

find [OPTION]... [查找路徑] [查找條件] [處理動作]

查找路徑:指定具體目標路徑;默認爲當前目錄

查找條件:指定的查找標準,可以文件名、大小、類型、權限等標準進行;默認爲找出指定路徑下的所有文件

處理動作:對符合條件的文件做操作,默認輸出至屏幕

………………………………………………………………………………………………………………………

查找條件:

表達式:選項和測試(常爲布爾型)

………………………………………………………………………………………………………………………

根據文件名和inode查找

    -name "文件名稱":支持使用glob

    *, ?, [], [^]

    -iname"文件名稱":不區分字母大小寫

    -inumn 按inode號查找

    -regex "PATTERN":基於正則表達式模式查找文件,匹配的是整個路徑而非其名

示例:查找包含有字符串“what”的文件

[root@localhost test]# find / -name *what* -ls
72662849    4 drwxr-xr-x   2 root     root         4096 7月 20 00:36 /var/lib/yum/yumdb/v/9879449b2e44ada0445cf495a38c3fd10c942c54-virt-what-1.13-6.el7-x86_64
2536807    4 -rw-r--r--   1 root     root         2836 6月 10  2014 /var/cache/man/cat1/whatis.1.gz
35799386   48 -rwxr-xr-x   1 root     root        46456 6月 10  2014 /usr/bin/whatis
...

………………………………………………………………………………………………………………………

根據屬主、屬組查找

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

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

    -uidUserID:查找屬主爲指定的UID號的文件

    -gidGroupID:查找屬組爲指定的GID號的文件

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

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

示例:查看/下屬於用戶fedore的文件,或沒有屬主的文件

[root@localhost test]# find / -user fedore -ls
find: ‘/proc/10542/task/10542/fd/6’: 沒有那個文件或目錄
find: ‘/proc/10542/task/10542/fdinfo/6’: 沒有那個文件或目錄
find: ‘/proc/10542/fd/6’: 沒有那個文件或目錄
find: ‘/proc/10542/fdinfo/6’: 沒有那個文件或目錄
74331703    0 -rw-rw----   1 fedore   mail            0 8月  2 21:49 /var/spool/mail/fedore
1477708    4 drwx------   3 fedore   fedore       4096 8月 15 17:11 /home/fedore
35996645    0 drwxr-xr-x   4 fedore   fedore         37 7月 19 23:54 /home/fedore/.mozilla
73207822    0 drwxr-xr-x   2 fedore   fedore          6 6月 10  2014 /home/fedore/.mozilla/extensions
101849766    0 drwxr-xr-x   2 fedore   fedore          6 6月 10  2014 /home/fedore/.mozilla/plugins
1477714    4 -rw-r--r--   1 fedore   fedore         18 11月 20  2015 /home/fedore/.bash_logout
1477721    4 -rw-------   1 fedore   fedore        152 8月 15 17:11 /home/fedore/.history
2538688    4 -rw-r--r--   1 fedore   fedore        237 8月 15 16:45 /home/fedore/.bash_profile
2538686    4 -rw-r--r--   1 fedore   fedore        273 8月 15 16:49 /home/fedore/.bashrc
2356350    4 -rw-------   1 fedore   fedore        134 8月 15 17:01 /home/fedore/.Xauthority
[root@localhost test]# find / -nouser -ls
find: ‘/proc/10540/task/10540/fd/6’: 沒有那個文件或目錄
find: ‘/proc/10540/task/10540/fdinfo/6’: 沒有那個文件或目錄
find: ‘/proc/10540/fd/6’: 沒有那個文件或目錄
find: ‘/proc/10540/fdinfo/6’: 沒有那個文件或目錄
101603081    0 -rw-r--r--   1 4001     root            0 8月 14 14:47 /tmp/3fstab2

………………………………………………………………………………………………………………………

根據文件類型查找

    -type TYPE:

    f: 普通文件

    d: 目錄文件

    l: 符號鏈接文件

    s:套接字文件

    b: 塊設備文件

    c: 字符設備文件

    p: 管道文件

示例:查找/test下的普通文件

[root@localhost test]# find /test/ -type f -ls
1832646    4 -rwxr-xr-x   1 root     root          399 8月 16 20:44 /test/scrip2

………………………………………………………………………………………………………………………

組合條件

    與:-a

    或:-o

    非:-not, !

示例:查找/tmp下屬於root且文件類型爲普通文件的文件

[root@localhost test]# find /tmp/ -user root -a -type f -ls
74330358    4 -rw-r-----   1 root     root         3092 8月 12 21:31 /tmp/vmware-root/vmware-apploader-6127.log
74330359    4 -rw-r-----   1 root     root         3092 8月 12 21:31 /tmp/vmware-root/vmware-apploader-6135.log
...

………………………………………………………………………………………………………………………

根據文件大小來查找

    -size [+|-]#UNIT

    常用單位:k, M, G

    #UNIT: (#-1, #]

    如:6k 表示(5k,6k]

    -#UNIT:[0,#-1]

    如:-6k 表示[0,5k]

    +#UNIT:(#,∞)

    如:+6k 表示(6k,∞)

示例:查找/etc下大於1M的文件

[root@localhost test]# find /etc -size +1M -ls   
102807508 1304 -rw-------   1 root     root      1333123 8月  2 10:09 /etc/selinux/targeted/contexts/files/file_contexts.bin
36013992 3688 -rw-r--r--   1 root     root      3773309 8月  2 10:09 /etc/selinux/targeted/policy/policy.29
72664102 6852 -r--r--r--   1 root     root      7014922 7月 20 00:38 /etc/udev/hwdb.bin
34828897 1336 -rw-r--r--   1 root     root      1367395 3月  6  2015 /etc/brltty/zh-tw.ctb

………………………………………………………………………………………………………………………

根據時間戳

以“天”爲單位

    -atime[+|-]#,

    #: [#,#+1)

    +#: [#+1,∞]

    -#: [0,#)

    -mtime

    -ctime

以“分鐘”爲單位

    -amin

    -mmin

    -cmin

示例:查找/etc文件夾下2天內被訪問過的文件

[root@localhost test]# find /etc -atime -2 -ls
36017835    4 -rw-r--r--   1 root     root           19 7月 20 00:36 /etc/locale.conf
36017836    4 -rw-r--r--   1 root     root           22 7月 20 00:36 /etc/hostname
33554565    4 -rw-r--r--   1 root     root         1309 8月 17 08:03 /etc/tpvmlp.conf
...

………………………………………………………………………………………………………………………

根據權限查找

    -perm [/|-]MODE

    MODE: 精確權限匹配

    /MODE:任何一類(u,g,o)對象的權限中只要能一位匹配即可,或關係, 

    “-perm +mode”從CentOS7後被“-perm /mode”格式替代

    -MODE:每一類對象都必須同時擁有指定權限,與關係

示例:查找/tmp下至少有一類對象有寫權限的文件

[root@localhost ~]# find /tmp -perm /222 -ls
100663425    4 drwxrwxrwt  15 root     root         4096 8月 17 17:36 /tmp
34305371    0 drwxrwxrwt   2 root     root            6 7月 20 00:04 /tmp/.Test-unix
69465462    0 drwxrwxrwt   2 root     root           15 8月 17 08:02 /tmp/.X11-unix
74098510    0 srwxrwxrwx   1 root     root            0 8月 17 08:02 /tmp/.X11-unix/X0
101599413    0 drwxrwxrwt   2 root     root            6 7月 20 00:04 /tmp/.XIM-unix
760765    0 drwxrwxrwt   2 root     root            6 7月 20 00:04 /tmp/.font-unix
34305372    4 drwxrwxrwt   2 root     root         4096 8月 17 08:03 /tmp/.ICE-unix
...

………………………………………………………………………………………………………………………

處理動作

    -print:默認的處理動作,顯示至屏幕;

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

    -delete:刪除查找到的文件;

    -fls /PATH/TO/SOMEFILE:查找到的所有文件的長格式信息保存至指定文件中

    -ok COMMAND {} \; 對查找到的每個文件執行由COMMAND指定的命令;

對於每個文件執行命令之前,都會交互式要求用戶確認

    -exec COMMAND {} \; 對查找到的每個文件執行由COMMAND指定的命令

find傳遞查找到的文件路徑至後面的命令時,是先查找出所有符合條件的文件路徑,並一次性傳遞給後面的命令;但是有些命令不能接受過長的參數,此時命令執行可能會失敗,下面方式可規避此問題

    find | xargs COMMAND


示例:1)查找/test下名爲scrip2的文件,並用cat查看其內容,使用兩種方式;2)將搜索到的scrip2文件的長格式信息保存在/test/scrip1中

[root@localhost test]# find /test -name scrip2 -exec cat {} \;
#!/bin/bash
#
[ $# -lt 1 ] && echo "please give one IP address" && exit 1
[ $# -gt 1 ] && echo "this script just match one IP address" && exit 2
[ $# -eq 1 ] && [[ $1 =~ (([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4])\.){3}([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4]) ]] && ping -c 1 $1 | sed -n '2p'|grep -o '^64' >> /dev/null && echo "該IP地址可訪問" || echo "該IP地址不可訪問"
[root@localhost test]# find /test -name scrip2 | xargs cat
#!/bin/bash
#
[ $# -lt 1 ] && echo "please give one IP address" && exit 1
[ $# -gt 1 ] && echo "this script just match one IP address" && exit 2
[ $# -eq 1 ] && [[ $1 =~ (([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4])\.){3}([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4]) ]] && ping -c 1 $1 | sed -n '2p'|grep -o '^64' >> /dev/null && echo "該IP地址可訪問" || echo "該IP地址不可訪問"


2)將搜索到的scrip2文件的長格式信息保存在/test/scrip1中

[root@localhost test]# find /test -name scrip2 -fls /test/scrip1
[root@localhost test]# cat scrip1
1832646    4 -rwxr-xr-x   1 root     root          399 8月 16 20:44 /test/scrip2




locate與find的不同

locate由於非實時因此會查找到最近刪除的文件,而find則不會。上述的不同導致查找的結果有所不同。

示例:在/test/文件下有兩個文件scrip1、scrip2,刪除scrip1,然後在搜scrip1

[root@localhost test]# stat /var/lib/mlocate/mlocate.db    
  文件:"/var/lib/mlocate/mlocate.db"
  大小:2771084         塊:5416       IO 塊:4096   普通文件
設備:fd00h/64768d      Inode:35764072    硬鏈接:1
權限:(0640/-rw-r-----)  Uid:(    0/    root)   Gid:(   21/ slocate)
環境:system_u:object_r:locate_var_lib_t:s0
最近訪問:2016-08-17 16:03:17.734189941 +0800
最近更改:2016-08-17 09:10:04.982775027 +0800
最近改動:2016-08-17 09:10:04.983775043 +0800
創建時間:-

先查看下該索引數據庫的最新改動時間,該時間是上午的,所以現在我們刪除scrip1文件後locate是可以搜到的。

[root@localhost test]# ll
總用量 8
-rw-r--r--. 1 root root  82 8月  17 18:03 scrip1
-rwxr-xr-x. 1 root root 399 8月  16 20:44 scrip2
[root@localhost test]# rm scrip1
rm:是否刪除普通文件 "scrip1"?y
[root@localhost test]# ll
總用量 4
-rwxr-xr-x. 1 root root 399 8月  16 20:44 scrip2

刪除scrip1,然後搜索它

[root@localhost test]# locate scrip1 
/test/scrip1
[root@localhost test]# find /test/ -name scrip1
[root@localhost test]#

比較結束。通過結果,如果我們要求搜索結果靠譜最好還是使用find。




爲了對find有更深的瞭解下面舉了關於find的8個例子


1、查找/var目錄下屬主爲root,且屬組爲mail的所有文件

[root@localhost ~]# find /var/ -user root -group mail -ls
67151194    4 drwxrwxr-x   2 root     mail         4096 8月 15 16:37 /var/spool/mail
72699698    4 -rw-------   1 root     mail         2220 8月  2 19:41 /var/spool/mail/root


2、查找/var目錄下不屬於root、fedore、mail的所有文件

[root@localhost ~]# find /var/ -not -user root -a -not -user fedore -a -not -user mail -ls
69508348    0 drwxr-xr-x   2 unbound  unbound        21 7月 20 00:05 /var/lib/unbound
69508349    4 -rw-r--r--   1 unbound  unbound       409 11月 20  2015 /var/lib/unbound/root.key
780655    0 drwx------   2 tss      tss             6 11月 21  2015 /var/lib/tpm
...


3、查找/var目錄下最近一週內其內容修改過,同時屬主不爲root,也不是postfix的文件

[root@localhost ~]# find /var/ -mtime -7 -a -not -user root -a -not -user postfix -ls
69508348    0 drwxr-xr-x   2 unbound  unbound        21 7月 20 00:05 /var/lib/unbound
780655    0 drwx------   2 tss      tss             6 11月 21  2015 /var/lib/tpm
101711459    0 drwxr-xr-x   3 colord   colord         50 7月 19 16:46 /var/lib/colord


4、查找當前系統上沒有屬主或屬組,且最近一個周內曾被訪問過的文件

[root@localhost ~]# find / -nouser -a -atime -7 -ls
find: ‘/proc/2254/task/2254/fd/6’: 沒有那個文件或目錄
find: ‘/proc/2254/task/2254/fdinfo/6’: 沒有那個文件或目錄
find: ‘/proc/2254/fd/6’: 沒有那個文件或目錄
find: ‘/proc/2254/fdinfo/6’: 沒有那個文件或目錄
101603081    0 -rw-r--r--   1 4001     root            0 8月 14 14:47 /tmp/3fstab2


5、查找/etc目錄下大於1M且類型爲普通文件的所有文件

[root@localhost ~]# find /etc -size +1M -a -type f -ls
102807508 1304 -rw-------   1 root     root      1333123 8月  2 10:09 /etc/selinux/targeted/contexts/files/file_contexts.bin
36013992 3688 -rw-r--r--   1 root     root      3773309 8月  2 10:09 /etc/selinux/targeted/policy/policy.29
72664102 6852 -r--r--r--   1 root     root      7014922 7月 20 00:38 /etc/udev/hwdb.bin
34828897 1336 -rw-r--r--   1 root     root      1367395 3月  6  2015 /etc/brltty/zh-tw.ctb


6、查找/etc目錄下所有用戶都沒有寫權限的文件

[root@localhost ~]# find /etc/ -not -perm /222 -ls  
190164  196 -r--r--r--   1 root     root       198453 7月 19 23:59 /etc/pki/ca-trust/extracted/java/cacerts
33828600  352 -r--r--r--   1 root     root       359773 7月 19 23:59 /etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt
67873473  264 -r--r--r--   1 root     root       266702 7月 19 23:59 /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
...


7、查找/etc目錄下至少有一類用戶沒有執行權限的文件

[root@localhost ~]# find /etc/ -not -perm -222 -ls
36017835    4 -rw-r--r--   1 root     root           19 7月 20 00:36 /etc/locale.conf
36017836    4 -rw-r--r--   1 root     root           22 7月 20 00:36 /etc/hostname
35930065    4 -rw-r--r--   1 root     root          163 7月 19 23:54 /etc/.updated
...


8、查找/etc/init.d目錄下,所有用戶都有執行權限,且其它用戶有寫權限的文件

[root@localhost ~]# find /etc/init.d/ -perm -113


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