文件查找
介紹:在文件系統上查找符合條件的文件。
文件查找:
- 非實時查找(數據庫查找):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
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