linux 文件查找詳解


文件查找

介紹:在文件系統上查找符合條件的文件。

文件查找:

  • 非實時查找(數據庫查找):locate
  • 實時查找:find

1、locate

  • locate 查詢系統上預建的文件索引數據庫 /var/lib/mlocate/mlocate.db
  • 索引的構建是在系統較為空閑時自動進行(周期性任務),執行updatedb可以更新數據庫
  • 索引構建過程需要遍歷整個根文件系統,很消耗資源
  • locate和updatedb命令來自於mlocate包

工作特點:

  • 查找速度快
  • 模糊查找
  • 非實時查找
  • 搜索的是文件的全路徑,不僅僅是文件名
  • 可能只搜索用戶具備讀取和執行權限的目錄

格式:

locate [OPTION]...[PATTERN]...

常用選項:

-i 不區分大小寫的搜索
-n N 只列舉前N個匹配項目
-r 使用基本正則表達式

范例:

#搜索名稱或路徑中包含“conf”的文件
locate conf

#使用Regex來搜索以“.conf”結尾的文件
locate -r '\.conf$'

范例:locatedb創建數據庫

dnf -y install mlocate 
locate conf
updatedb
ll /var/lib/mlocate/mlocate.db
locate -n 3 conf

范例:文件新創建和刪除,無法馬上更新locate數據庫

touch test.log
locate test.log
updatedb
locate test.log
touch test2.log
locate test2.log
rm -f test2.log
locate test2.log
[root@centos8 ~]#locate -n 10 -ir '\.CONF$'
/boot/loader/entries/5b85fc7444b240a992c42ce2a9f65db5-0-rescue.conf
/boot/loader/entries/5b85fc7444b240a992c42ce2a9f65db5-4.18.0-147.el8.x86_64.conf
/etc/autofs.conf
/etc/autofs_ldap_auth.conf
/etc/dracut.conf
/etc/fuse.conf
/etc/host.conf
/etc/idmapd.conf
/etc/kdump.conf
/etc/krb5.conf

2.find

find是實時查找工具,通過遍歷指定路徑完成文件查找

工作特點:

  • 查找速度略慢
  • 實時查找
  • 精確查找
  • 查找條件豐富
  • 可能只搜索用戶具備的讀取和執行權限目錄

格式:

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

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

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

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

2.1 指定搜索目錄層級

-maxdepth level 最大搜索目錄深度,指定目錄下的文件為第1級
-mindepth level 最小搜索目錄深度

范例:
find /etc -maxdepth 2 -mindepth 2

2.2 對每個目錄先處理目錄內的文件,再處理目錄本身

-depth 
-d

范例:
tree /data/test
/data/test
├── f1.txt
├── f2.txt
└── test2
   └── test3
       ├── f3.txt
       └── f4.txt
4 directories, 2 files

[root@centos8 data]#find /data/test
/data/test
/data/test/f1.txt
/data/test/f2.txt
/data/test/test2
/data/test/test2/test3
/data/test/test2/test3/f3.txt
/data/test/test2/test3/f4.txt

[root@centos8 data]#find /data/test -depth
/data/test/f1.txt
/data/test/f2.txt
/data/test/test2/test3/f3.txt
/data/test/test2/test3/f4.txt
/data/test/test2/test3
/data/test/test2
/data/test

2.3 根據文件名和inode查找

-name "文件名稱"        #支持使用glob,如:*,?,[],[^],通配符要加雙引號引起來
-iname "文件名稱"       #不區分字母大小寫
-inum n    						 #按inode號查找
-samefile name 				 #相同inode號的文件
-links n							 #鏈接數為n的文件
-regex "PATTERN"			 #以PATTERN匹配整個文件路徑,而非文件名稱
范例:
find -name snow.png
find -iname snow.png
find / -name ".txt"
find /var -name "log*"

find -regex ".*\.txt$"
./scripts/b.txt
./f1.txt

2.4 根據屬主、屬組查找

-user USERNAME #查找屬主為指定用戶(UID)的文件
-group GRPNAME #查找屬組為指定組(GID)的文件
-uid UserID #查找屬主為指定的UID號的文件
-gid GroupID #查找屬組為指定的GID號的文件
-nouser #查找沒有屬主的文件
-nogroup #查找沒有屬組的文件

2.5 根據文件類型查找

-type TYPE
TYPE可以是以下形式:
f: 普通文件
d: 目錄文件
l: 符號鏈接文件
s:套接字文件
b: 塊設備文件
c: 字符設備文件
p: 管道文件

范例:
#查看/home的目錄
find /home –type d -ls

2.6 空文件或目錄

-empty
范例:
find /app -type d -empty

2.7 組合條件

與:-a ,默認多個條件是與關系
或:-o
非:-not   !

范例:
[root@centos8 ~]#find /etc/ -type d -o -type l |wc -l
307
[root@centos8 ~]#find /etc/ -type d -o -type l -ls |wc -l
101
[root@centos8 ~]#find /etc/ \( -type d -o -type l \)   -ls |wc -l
307
德 摩根定律:
(非 A) 或 (非 B) = 非(A 且 B) 
(非 A) 且 (非 B) = 非(A 或 B) 
示例:
!A -a !B = !(A -o B)
!A -o !B = !(A -a B)


[root@centos8 data]#find ! \( -type d -a -empty \)| wc -l
56
[root@centos8 data]#find ! -type d -o ! -empty |wc -l
56
[mage@centos8 data]$find !  -user wang   ! -user mage
.
./script40
./script40/backup
./script40/backup/args.sh
./script40/backup/chook_rabbit.sh
./script40/backup/disk_check.sh
./script40/backup/ping.sh
./script40/backup/systeminfo.sh
./script40/backup/test_read.sh
./script40/backup/test.sh
./script40/if_bmi.sh
./script40/case_yesorno.sh
./script40/case_yesorno2.sh
./script40/b.txt
./f1.txt
./test
./test/f1.txt.link
./f1.txtlink
./test2

[root@centos8 home]#find ! \( -user wang -o -user mage \)
.
./xiaoming
./xiaoming/.bash_logout
./xiaoming/.bash_profile
./xiaoming/.bashrc
[root@centos8 home]#f
#找出/tmp目錄下,屬主不是root,且文件名不以f開頭的文件
find /tmp \( -not -user root -a -not -name 'f*' \) -ls
find /tmp -not \( -user root -o -name 'f*' \) –ls

2.8 排除目錄

#查找/etc/下,除/etc/security目錄的其它所有.conf后綴的文件
find /etc -path '/etc/security' -a -prune -o -name "*.conf"
#查找/etc/下,除/etc/security和/etc/systemd,/etc/dbus-1三個目錄的所有.conf后綴的文件
find /etc \( -path "/etc/security" -o -path "/etc/systemd"  -o -path "/etc/dbus-
1" \) -a -prune -o -name "*.conf"
#排除/proc和/sys目錄
find / \( -path "/sys" -o -path "/proc" \) -a -prune -o -type f -a -mmin -1

2.9 根據文件大小來查找

shell下如何創建指定大小的臨時文件?
/dev/zero 0輸入設備文件,跟/dev/null一樣的偽文件,它產生連續不斷的null流(二進制的零流,不是ascii碼),寫入它的輸出文件。作用是可以用它來創建一個指定大小的null文件也稱為臨時文件。
命令如下:

dd if=/dev/zero of=f1.img bs=1M count=100 //說明:創建一個名為f1.im的100M大小文件



-size [+|-] #UNIT #常用單位:k, M, G,c(byte),注意大小寫敏感
 #UNIT: #表示(#-1, #],如:6k 表示(5k,6k]
-#UNIT #表示[0,#-1],如:-6k 表示[0,5k]
+#UNIT #表示(#,∞),如:+6k 表示(6k,∞)

解釋說明:#UNIT參數可以看做一個坐標軸


例如 -6K 6K +6K 代表一個+有理數的取值范圍。。
-6K 代表[0K ~ 5K ]  前半部 包含0k 和 5K
6K  代表(5K-6K)    中部  不含5K、6K
+6K  代表[6K ~ ∞)   后部 包含6K 到無窮大


范例: 查找根目錄下 大於10g的文件
find /  -size +10G
[root@centos8 ~]#find / -size +10G
/proc/kcore
find: ‘/proc/25229/task/25229/fd/6’: No such file or directory
find: ‘/proc/25229/task/25229/fdinfo/6’: No such file or directory
find: ‘/proc/25229/fd/5’: No such file or directory
find: ‘/proc/25229/fdinfo/5’: No such file or directory
[root@centos8 ~]#ll -h /proc/kcore
-r-------- 1 root root 128T Dec 14  2020 /proc/kcore
[root@centos8 ~]#du -sh /proc/kcore
0 /proc/kcore

2.10 根據時間戳

#以“天”為單位
-atime [+|-]# 
# #表示[#,#+1)
+# #表示[#+1,∞]
-# #表示[0,#)
-mtime
-ctime
#以“分鍾”為單位
-amin
-mmin
-cmin

image-20211024174915649

2.11 根據權限查找

-perm [/|-]MODE
MODE  #精確權限匹配


或者: /MODE #任何一類(u,g,o)對象的權限中只要能一位匹配即可,或關系,+ 從CentOS 7開始淘汰
並且: -MODE #每一類對象都必須同時擁有指定權限,與關系
0 表示不關注
說明:
find -perm 755 會匹配權限模式恰好是755的文件
只要當任意人有寫權限時,find -perm /222就會匹配
只有當每個人都有寫權限時,find -perm -222才會匹配
只有當其它人(other)有寫權限時,find -perm -002才會匹配

2.12 正則表達式

-regextype type
   Changes the regular expression syntax understood by -regex and -iregex tests 
which occur later on the command line.   Currently-implemented types are 
emacs (this is the default), posix-awk, posix-basic, posix-egrep and posixextended.
-regex pattern
   File name matches regular expression pattern. This is a match on the whole 
path, not a search.   For example, to match a file named `./fubar3', you can 
use the regular expression `.*bar.' or `.*b.*3', but not `f.*r3'. The regular 
expressions understood by find are by default Emacs Regular Expressions, but 
this can be changed with the -regextype option.


范例:

find /you/find/dir -regextype posix-extended -regex "regex"

2.13 處理動作

-print:默認的處理動作,顯示至屏幕
-ls:類似於對查找到的文件執行"ls -dils"命令格式輸出
-fls file:查找到的所有文件的長格式信息保存至指定文件中,相當於 -ls > file
-delete:刪除查找到的文件,慎用!
-ok COMMAND {} \; 對查找到的每個文件執行由COMMAND指定的命令,對於每個文件執行命令之前,都會
交互式要求用戶確認
-exec COMMAND {} \; 對查找到的每個文件執行由COMMAND指定的命令
{}: 用於引用查找到的文件名稱自身
范例:
#備份配置文件,添加.orig這個擴展名
find  -name  ".conf"  -exec  cp {} {}.orig \;
#提示刪除存在時間超過3天以上的joe的臨時文件
find /tmp -ctime +3 -user joe -ok rm {} \;
#在主目錄中尋找可被其它用戶寫入的文件
find ~ -perm -002  -exec chmod o-w {} \;
#查找/data下的權限為644,后綴為sh的普通文件,增加執行權限
find /data –type f -perm 644  -name "*.sh" –exec chmod 755 {} \;

3.參數替換 xargs

一句話來說,xargs 用來接收標准輸入或者前面指令的結果 動態輸入給后面參數或者輸出。也可作為傳參

詳解:

由於很多命令不支持管道|來傳遞參數,xargs用於產生某個命令的參數,xargs 可以讀入 stdin 的數

據,並且以空格符或回車符將 stdin 的數據分隔成為參數

另外,許多命令不能接受過多參數,命令執行可能會失敗,xargs 可以解決

注意:文件名或者是其他意義的名詞內含有空格符的情況

find 經常和 xargs 命令進行組合,形式如下:

find | xargs COMMAND

范例:

#顯示10個數字
[root@centos8 ~]#seq 10 | xargs
1 2 3 4 5 6 7 8 9 10
#刪除當前目錄下的大量文件
ls | xargs   rm
#
find  -name "*.sh" | xargs ls -Sl
[root@centos8 data]#echo {1..10} |xargs 
1 2 3 4 5 6 7 8 9 10
[root@centos8 data]#echo {1..10} |xargs -n1 
123456789
10
[root@centos8 data]#echo {1..10} |xargs -n2
1 2 3 4 5 6 7 8 9 10
#批量創建和刪除用戶
echo user{1..10} |xargs -n1 useradd 
echo user{1..100} | xargs -n1 userdel -r

#這個命令是錯誤的
find /sbin/ -perm /700 | ls -l       
#查找有特殊權限的文件,並排序
find /bin/ -perm /7000 | xargs ls -Sl  
#此命令和上面有何區別?
find /bin/ -perm -7000 | xargs ls -Sl  
#以字符nul分隔
find -type f -name "*.txt” -print0 | xargs -0 rm 
#並發執行多個進程
seq 100 |xargs -i -P10 wget -P /data   http://10.0.0.8/{}.html

Xargs 的缺點:

假如:touch 幾個文件, touch a b;touch 'a b';

此時當前目錄下就是產生3個文件,如下:ls

a b a b

find -type f | xargs rm //此時是無法進行刪除操作的

原因為:默認空格是作為xargs的分隔符存在的,a b文件中含有空格,故報錯!

那么以上問題如何解決呢?

可以使用ASCII中的0字符來作為切割符號:print0 ==>null

find -type f -print0 |xargs -0 rm

下載bilibili視頻

#並行下載bilibili視頻
yum install python3-pip -y
pip3 install you-get
seq 10 | xargs -i -P3 you-get https://www.bilibili.com/video/BV1HZ4y1p7Bf?p={}

以上范例依賴Python環境,需要先安裝好Python環境。

練習

1、查找/var目錄下屬主為root,且屬組為mail的所有文件
2、查找/var目錄下不屬於root、lp、gdm的所有文件
3、查找/var目錄下最近一周內其內容修改過,同時屬主不為root,也不是postfix的文件
4、查找當前系統上沒有屬主或屬組,且最近一個周內曾被訪問過的文件
5、查找/etc目錄下大於1M且類型為普通文件的所有文件
6、查找/etc目錄下所有用戶都沒有寫權限的文件
7、查找/etc目錄下至少有一類用戶沒有執行權限的文件
8、查找/etc/init.d目錄下,所有用戶都有執行權限,且其它用戶有寫權限的文件


答案:
1、find /var -user root -a -group mail
2、find /var/ !\( -user root -o -user lp -o -user -gdm \)
3、find /var -mtime -7 -a -nouser root -a -nouser postfix

find /var/ -mtime -7 -a -not \( -user root -o -user postfix \)
4、find /. -nouser -o -nogroup -atime -7
5、find /etc -size +1M -a -type f
6、find /etc  -not -perm /222 -a -not -type d -ls
7、find /etc ! -perm -111 -ls 
8、find /etc/init.d -perm /113  -ls

image-20211024131218775


免責聲明!

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



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