linux 搜索工具
阿新 • • 發佈:2017-08-11
-type 屬於 一行 表達式 文件的 ls命令 都沒有 相同 查找條件 大家好!本文為大家介紹linux 的搜索工具:locate、find,更精確的查找工具。之前我們學過ls |grep 也能達到搜索文件的功能,但ls是基於文件名的查找,雖然搭配grep能按照一定的條件去查找文件,又因為每個文件的格式不唯一,所以這種方法也不總適用。
下面為大家介紹簡單精確的查找工具:
1、locate: 基於數據庫的查詢,非實時性,對新創建的文件需要更新數據庫。local是基於文件全路徑的模糊查詢,查詢時會判斷權限
格式:locate KEYWORD
-i 忽略大小寫
-n X 只列舉前N個匹配的項目
updatedb 更新locate數據庫 /var/lib/mlocate/mlocate.db
-r 支持正則
eg: locate conf 搜索名稱或路徑中帶有“conf ”的文件
locate -r ‘\.conf$’ 使用Regex 來搜索以“.conf
2、find : 實時查詢 ,速度肯定沒locate快。但它可以基於文件大小、屬主、屬組、訪問時間、文件名、文件類型、硬鏈接等更精確的查找方式。查找時也需要具有相應權限(rx)
(1)語法: find [OPTION]... [ 查找路徑] [ 查找條件] [ 處理動作]
查找路徑:指定具體目標路徑;默認為當前目錄
查找條件:指定的查找標準,可以文件名、大小、類型、
權限等標準進行;默認為找出指定路徑下的所有文件
處理動作:對符合條件的文件做操作,默認輸出至屏幕
(2)find
-maxdepth level 最大搜索深度
-minxdepth level 最小搜索深度
-name 基於名稱的精確查找,支持通配符*, ?, [], [^]
eg:find -name “my*” 搜索當前目錄(含子目錄)中,所有文件名以my開頭的文件
-iname 基於名稱忽略大小寫的精確查找查找
-empty : 空的檔案-gid n or -group name : gid 是 n 或是 group 名稱是 name
-ipath p, -path p : 匹配一個路徑名,ipath 會忽略大小寫
-inum 基於inode查找
-samefile "文件名" 基於相同inode號的查找(查找硬鏈接)
-links n 硬鏈接數為n的文件
-regex “PATTERN”支持正則 默認為(emacs標準),匹配全路徑,而不只是文件名
eg:find -regex ".*f[1-9]" 因為匹配的是全路徑所以".*"要加到前面
-regextype egrep -regex 支持egrep同標準的正則
-user 用戶名 基於文件owner的查找
-group 組名 基於文件group的查找
-uid userid 基於文件uid的查找
-gid groupid 基於文件gid的查找
-nouser 查找沒有owner的文件
-nogroup 查找沒有group的文件
-type 基於文件類型的查找
? f: 普通文件
? d: 目錄文件
? l: 符號鏈接文件
? s:套接字文件
? b: 塊設備文件
? c: 字符設備文件
? p: 管道文件
(3)組合條件:-a與 、-o或 、-not=! 非
德摩根定律:
!A -a !B = !(A -o B)
!A -o !B = !(A -a B)
eg: find /tmp \( -not -user root -a -not -name ‘f*‘ \) -ls
find /tmp -not \( -user root -o -name ‘f*‘ \) –ls
需要註意的是f*表示文件名要以f開頭
*f*表示只要文件名包含f即可
\(代表一個復雜表達式的開始
\)代表一個復雜表達式的結束
(4)排除目錄
find [-path ..] [expression] 在路徑列表的後面的是表達式
-path "/usr/sam" -prune -o -print 是 -path "/usr/sam" -a -prune -o -print 的簡寫表達式按順序求值, -a 和 -o 都是短路求值,與 shell 的 && 和 || 類似如果 -path "/usr/sam" 為真,則求值 -prune , -prune 返回真,與邏輯表達式為真;否則不求值 -prune,與邏輯表達式為假。如果 -path "/usr/sam" -a -prune 為假,則求值 -print ,-print返回真,或邏輯表達式為真;否則不求值 -print,或邏輯表達式為真。
eg:find /etc -path ‘/etc/sane.d‘ -a -prune -o -name "*.conf"
在/etc目錄下查找文件名以.conf結尾的文件(除/etc/sane.d目錄不查詢)
find /etc \( -path ‘/etc/sane.d‘ -o -path ‘/etc/fonts‘ \) -a -prune -o -name "*.conf"
在/etc目錄下查找文件名以.conf結尾的文件(除/etc/sane.d目錄、/etc/fonts不查詢)
(5)基於文件大小查找
-size [+|-]#UNIT 根據文件大小來查找
常用單位:k, M, G,c(byte)
#UNIT: (#-1, #]如:6k 表示(5k,6k]
-#UNIT:[0,#-1]如:-6k 表示[0,5k]
+#UNIT:(#,∞)如:+6k 表示(6k,∞)
find 中要想使用正規正則表達式,需要用選項 -regex "pattern",
註意 find 的常用選項 -name 是不支持正則表達式的,充其量只能說 -name 選項支持通配符 * ? []
(6)基於時間戳查找
以“天”為單位;
-atime [+|-]#,
#: [#,#+1)
+#: [#+1,∞]
-#: [0,#)
-mtime
-ctime
以“分鐘”為單位:
-amin
-mmin
-cmin
(7)基於權限查找
-perm [ mode|+mode|-mode]
mode:精確權限匹配
+mode[/mode] 任何一類(u,g,o)對象的權限中只要能一位匹配即可,或關系,+ 從centos7開始淘汰
-mode 每一類對象都必須同時擁有指定權限,與關系0 表示不關註
(8)處理動作:
-print 默認
-delete 直接刪除所查找到的文件,不詢問。
-ls 長列出所查找到的文件
-fls file 將查找到的文件長列出導入到指定文件。
> file
-ok command {} \; 對查找到的每個文件當做下一命令的參數去執行(交互式)
-exec command {} \; 對查找到的每個文件當做下一命令的參數去執行(非交互式)
{}: 用於引用查找到的文件名稱自身
那些天走過的彎路 :
問題描述:
find -name "f2" -o -name "f3" -a -exec echo {} \;
只會把最後一個查找條件匹配的結果傳遞給exec後的命令做參數
find \( -name "f2" -o -name "f3" \) -a -exec echo {} \;
會把括號裏所有的查詢結果,作為參數傳遞給exec後的命令做參數
困擾:
find的查詢順序不應該是順序執行麽?當 f2 沒匹配到返回false值,再去匹配第二個條件f3。
那麽應該只要匹配到一個條件返回一個true,就會通過-exec傳遞給命令了吧?
經過反復調試,發現find -name "f2" -o -name "f3" -a -exec echo {} \;
這種寫法只會把-exec前的條件匹配到的結果傳遞給後面的命令,而與find的查詢順序毫無關系
原理剖析:
find -name "f2" -o -name "f3" -exec echo {} \;
(1)不加括號會把-name "f3" -a -exec echo {} \;看成一個整體
(2)-exec 會把結果傳遞給命令,不會再顯示在標準輸出(相當於輸出重定向)
總結:
find把條件看成了兩個部分: -name "f2" 或者 -name "f3" -exec echo {}
(1)先來說f3,匹配到以後會把查詢結果傳遞給exec後的命令,然後執行
(2)-name "f2" 的查詢結果,原本應該在標準輸出顯示出來,但因為把結果傳遞給了-exec,
而exec又只傳遞f3的匹配結果,所以f2沒有顯示出來
練習:
1、查找/var目錄下屬主為root,且屬組為mail的所有文件
find /var -user root -a -group mail -ls
2、查找/var目錄下不屬於root、lp、gdm的所有文件
find /var -not \( -user root -o -user lp -o -user gdm \) -ls
3、查找/var目錄下最近一周內其內容修改過,同時屬主不為root,也不是postfix的文件
find /var/ -mtime -7 -not -user root -not -user postfix -ls
4、查找當前系統上沒有屬主或屬組,且最近一個周內曾被訪問過的文件
find / -nouser -o -nogroup -a -atime -7 -ls
5、查找/etc目錄下大於1M且類型為普通文件的所有文件
find /etc/ -size +1M -a -type f -ls
6、查找/etc目錄下所有用戶都沒有寫權限的文件
find /etc ! -perm /222 -ls
7、查找/etc目錄下至少有一類用戶沒有執行權限的文件
find /etc ! -perm -111 -ls
8、查找/etc/init.d目錄下,所有用戶都有執行權限,且其它
用戶有寫權限的文件
find /etc/init.d/ -perm -113 -ls
9、查找名字符合正則表達式的文件,註意前面的‘.*’(查找到的文件帶有目錄)
find ./ -regex .*so.*\.gz
10、查找目錄並列出目錄下的文件(為找到的每一個目錄單獨執行ls命令,沒有選項-print時文件列表前一行不會顯示目錄名稱)
find ./ -type d -print -exec ls {} \;
11、查找目錄並列出目錄下的文件(為找到的每一個目錄單獨執行ls命令,執行命令前需要確認)
find ./ -type d -ok ls {} \;
linux 搜索工具