2009-05-03

find 詳細指令及範例整理 [Linux]

find -遞歸地在層次目錄中處理文件

find [path] [expression]
[path]啟始路徑
[expression]查詢參數


選項 OPTIONS

所有的選項都總是返回真值,它們總會被執行,除非放在表達式中執行不到的地方。因此,清楚起見,最好把它們放在表達式的開頭部分。
-daystart
從當日起始時開始而不是從24小時之前,計算時間(for -amin, -atime, -cmin, -ctime, -mmin, and -mtime)。
-depth
先處理目錄的內容再處理目錄本身,(廣度優先搜尋法則)。
# 從文件系統的根目錄開始搜尋一個名為 CON.FILE 的文件。
find / -name "CON.FILE" -depth
-follow
不檢索符號鏈接。隱含了-noleaf。
-help, --help
列出 find 的命令行用法的概要,然後退出。
-maxdepth levels
進入命令行參數指定的目錄下層目錄時,最深不超過levels(一個非負整數)層。 `-maxdepth 0'意味著只在命令行參數指定的目錄中執行測試和動作。
# 在目錄樹的前三個級別中搜尋日誌文件。
find / -maxdepth 3 -name "*log"

# 只搜尋當前一層目錄下的 C 語言文件。
find . -maxdepth 1 -name “*.c”
-mindepth levels
不在levels(一個非負整數)層之內執行任何測試和動作。 `-mindepth 1'意味著處理所有的文件,除了命令行參數指定的目錄中的文件。
-mount
不進入處於其它文件系統之上的目錄。可以用-xdev代替,從而和一些其他版本的 find 兼容。
# 從當前目錄開始搜尋位於本文件系統中文件名以XC結尾的文件。
find . -name "*.XC" -mount

find / -name "*.txt" -mount 2> /dev/null
-noleaf
不為“目錄中子目錄數量比硬連接數少2”這種假設做優化。這個選項在搜索那些不遵循UNIX文件系統鏈接約定的文件系統時用,比如CD- ROM,MS-DOS文件系統或AFS卷的加載點。在普通的UNIX文件系統中,每個目錄至少有兩個硬連接,它的名字和它的'.'條目。另外,它的子目錄 (假如有)還會各有一個'..'鏈接到它。在 find 檢索一個目錄時,發現子目錄數比它的連接數少二時,它就知道目錄中的其他條目並非目錄(而是目錄樹中的葉(`leaf')節點)。除非需要檢索的是這個葉節點,否則沒必要去處理它。這樣可以帶來很大的搜索速度提升。
-version, --version
打印find的版本號然後退出。
-xdev
不進入處於其他文件系統之上的目錄。
find / -name "*.txt" -xdev 2> /dev/null

測試 TESTS

數字參數可以這樣給出:
+n
是比 n 大,
-n
是比 n 小,
n
正好是 n 。
-amin n
對文件的最近一次訪問是在n分鐘之前。
# 搜尋當前目錄下在5分鐘內被訪問過的文件。
find . -amin -5

# 搜尋在系統中最後10分鐘訪問的文件。
find / -amin -10
-anewer file
對文件的最近一次訪問比file修改時間要晚。如果命令行中-follow在-anewer之前,(也只有在這種情況下) -anewer會受-follow的影響。
-atime n
對文件的最近一次訪問是在n*24小時之前。
# 搜尋在系統中最後48小時訪問的文件。
find / -atime -2
-cmin n
對文件狀態的建立時間是在n分鐘之前。
-cnewer file
對文件狀態的最近一次修改比file修改時間要晚。如果命令行中-follow在-cnewer之前,(也只有在這種情況下) -cnewer會受-follow的影響。
-ctime n
對文件狀態的建立時間是在n*24小時之前。
-empty
文件是空的普通文件或者空目錄。
# 搜尋空文件。
find test -empty

# 搜尋在系統中為空的文件或者文件夾。
find / -empty
-false
總是false。
-fstype type
文件處於type類型的文件系統之上。有效的文件系統類型在不同版本的Unix中是不同的;一些Unix 中的不完全的文件系統類型列表是這樣:ufs, 4.2, 4.3, nfs, tmp, mfs, S51K, S52K.你可以用-printf加上%F指令來查看你的文件系統的類型。
find / -name "*.txt" -fstype vfat 2> /dev/null
-gid n
文件的數字形式的組ID是n。
# 列出由ID為100的組擁有的目錄。
find / -type d -gid 100
-group gname
文件屬於gname (也允許使用數字形式的組ID).
# 在/apps目錄下搜尋群組為 gem 的文件。
find /apps -group gem -print

# 搜尋在系統中 group 屬於 cat 的文件。
find / -group cat
-ilname pattern
和-lname類似,但是匹配時是不區分大小寫的。
-iname pattern
和-name類似,但是匹配時是不區分大小寫的。例如,`fo*' and `F??'模式與文件名`Foo', `FOO', `foo', `fOo'等等相匹配。
-inum n
文件的i結點數是n。
-ipath pattern
和-path類似,但是匹配時是不區分大小寫的。
-iregex pattern
和-regex類似,但是匹配時是不區分大小寫的。
-links n
文件有n個鏈接。
-lname pattern
文件是一個與pattern匹配的符號鏈接。元字符不會對`/'或`.'做特殊處理。
-mmin n
對文件數據的最近一次修改是在n分鐘之前。
# 搜尋在最近1小時內修改的所有文件。
find . -mmin -60

# 搜尋恰好在1小時時修改的所有文件。
find . -mmin 60

# 搜尋1小時以前修改的所有文件。
find . -mmin +1

# 搜尋在系統中最後5分鐘裡修改過的文件。
find / -mmin -5
-mtime n
對文件數據的最近一次修改是在n*24小時之前。
# 將過去系統上面 24 小時內有更動過內容 (mtime) 的檔案列出。
find / -mtime 0
find / –mtime –1

# 在當前目錄中搜尋更改時間在5日以上的文件。
find . -mtime +5

# 在系統根目錄下搜尋更改時間在5日以內的文件。
find / -mtime -5

# 在/var/adm目錄下搜尋更改時間在3日以前的文件。
find /var/adm -mtime +3
-name pattern
基本的文件名(將路徑去掉了前面的目錄)與shell模式pattern相匹配。元字符(`*', `?',還有`[]' )不會匹配文件名開頭的`.' 。使用-prune來略過一個目錄及其中的文件。查看-path的描述中的範例。
# 找出檔名為 passwd 這個檔案。
find / -name passwd

# 在當前目錄中搜尋任何副檔名為“java”的文件。
find . -name "*.java"

# 在/usr、/home /tmp 目錄搜尋所有 jar 文件。
find /usr /home /tmp -name "*.jar"

#在當前目錄中搜尋文件名以一個大寫字母開頭的文件。
find . -name "[A-Z]*" -print

# 在/etc目錄中搜尋文件名以host開頭的文件。
find /etc -name "host*" -print

# 在當前目錄搜尋文件名以兩個小寫字母開頭,跟著是兩個數字,最後是.txt的文件(ax37.txt)。
find . -name "[a-z][a-z][0-9][0-9].txt"
-newer file
對文件的最近一次修改比file修改時間要晚。如果命令行中-follow在-newer之前,(也只有在這種情況下) -newer會受-follow的影響。用在分辨兩個檔案之間的新舊關係是很有用。
# 搜尋更改時間在比temp文件新的文件。
find . -newer temp

# 尋找 /etc 底下的檔案,如果檔案日期比 /etc/passwd 新就列出。
find /etc -newer /etc/passwd
-nouser
沒有符合文件的數字形式的用戶ID的用戶。
# 搜尋系統中不屬於任何人的檔案。
find / -nouser

# 在當前目錄下搜尋使用者名稱非(ftp)的檔案
find . -nouser ftp
-nogroup
沒有符合文件的數字形式的組ID的組。
# 在系統根目錄開始搜尋無效群組的所有文件。
find / -nogroup

# 在當前目錄下搜尋群組名稱非(ftp)的檔案
find . -nogroup ftp
-path pattern
文件名與shell模式pattern相匹配。元字符不會對`/'或`.'做特殊處理。
# 因此,例如:
find . -path './sr*sc'

# 如果存在'./src/misc'的話,會將它打印出來。想要忽略一個完整的目錄樹,應當使用-prune而不是檢查目錄樹中所有的文件。
# 例如:要跳過'src/emacs'目錄和其中所有的文件和子目錄,把其他找到的文件打印出來,應當這樣:
find . -path './src/emacs' -prune -o -print

# 在當前目錄下搜尋 ./pics/pic_01.jpg, ./01/pics/pic_a1.jpg, ./02/pics/01/pic_aa.jpg 這些檔案
find . -path '*pics/*pic_*.jpg'
-perm mode
文件的權限位恰好是mode (八進製或符號)。 Symbolic modes use mode 0 as a point of departure.
# 在當前目錄下搜尋文件權限位為755的文件。
find . -perm 755

find . -type f -perm a=rwx

find . -type f -perm 777
-perm -mode
所有的權限位mode都被設置了的文件。
# 在當前目錄下搜尋檔案權限大於(744)的檔案,(744,774)
find . -perm -744
-perm +mode
任何權限位mode被設置了的文件。
# 搜尋檔案當中含有 SGID 或 SUID 或 SBIT 的屬性。
find / -perm +7000 

# 在當前目錄下搜尋檔案權限小於(744)的檔案,(600,444)
find . -perm +744
-regex pattern
文件名與正則表達式pattern匹配。這是對整個路徑的匹配,不是搜索文件。例如,要匹配名為`./fubar3'的文件,可以使用正則表達式`.*bar.'或者`.*b.*3',但是不能用`b.*r3'。
# 搜尋當前文件夾及子文件夾裡的同時含有b字符和3字符的文件。
find . -regex ‘.*b.*3′

# 在當前目錄下搜尋 pic_01.jpg, pic_03.jpg, pic_03.jpg 這些檔案
find . -regex '.*pic_[0-9]+\.jpg'
-size n[bckw]
文件使用了n單位個存儲單元。 可用單位如下:
  • `b' 512-byte blocks (預設)
  • `c' bytes
  • `w' 2-byte words
  • `k' Kilo bytes (1024 bytes)
  • `M' Mega bytes (1048576 bytes)
  • `G' Giga bytes (1073741824 bytes)
大小不會計入indirect blocks,但是會計入沒有真正分配空間的疏鬆文件中的塊。
# 找出系統中,大於 1MB 的檔案。
find / -size +1M

# 在當前目錄下搜尋長度超過10塊的文件(一塊等於512字節)。
find . -size +10

# 在當前目錄下搜尋文件長度大於 1M 字節的文件。
find . -size +1M

# 在 /home/apache 目錄下搜尋文件長度恰好為 100 字節的文件。
find /home/apache -size 100c
-true
總是true。
-type c
文件是c類型的。 類型可取值如下:
  • b 特殊塊文件(緩衝的)
  • c 特殊字符文件(不緩衝)
  • d 目錄
  • p 命名管道(FIFO)
  • f 普通文件
  • l 符號鏈接
  • s 套接字
  • D 門(Solaris特有)
# 在/etc目錄下搜尋所有的目錄。
find /etc -type d

# 搜尋當前文件系統中的所有目錄並排序。
find . -type d | sort

# 在當前目錄下搜尋除目錄以外的所有類型的文件。
find . ! -type d 

# 在/etc目錄下搜尋所有的符號鏈接文件。
find /etc -type l

# 找出 /var 目錄下,檔案類型為 Socket 的檔名有哪些?
find /var -type s

# 搜尋 /usr 目錄中的所有符號鏈接。
find /usr -type l
-uid n
文件的數字形式的用戶ID是n 。
-used n
文件最後一次存取是在最後一次修改它的狀態的n天之後。
-user uname
文件的所有者是uname (也可以使用數字形式的用戶ID).
# 在家目錄中搜尋文件的使用者為 sam 的文件。
find ~ -user sam

# 在 /etc 目錄下搜尋文件的使用者為 uucp 的文件。
find /etc -user uucp

# 搜尋 /home 底下屬於 vbird 的檔案。
find /home -user vbird
-xtype c
和-type相同,除非文件是一個符號鏈接。對於符號鏈接:如果沒有給出-follow ,如果文件是一個指向c類型文件的鏈接,那麼返回true;如果給出了-follow ,如果c是`l'那麼返回true。換句話說,對於符號鏈接,-xtype檢查那些-type不檢查的文件。

動作 ACTIONS

-delete
將搜尋出來的檔案刪除,如果成功刪除將回傳 ture。如果刪除失敗將丟出錯誤訊息。
# 刪除使用者名稱為(ftp)的檔案
find . -user ftp -delete
-exec command
執行command;如果命令返回狀態值0,那麼exec返回true。所有 find 其餘的命令行參數將作為提供給命令的參數,直到遇到一個由`;'組成的參數為止。命令的參數中,字符串`{}'將以正在處理的文件名替換。所有的`{}'都會被替換,不僅是在單獨的一個參數中。有些版本的 find 不是這樣做的。這些參數可能需要用`\'來escape或者用括號括住,防止它們被shell展開。命令是從起始目錄執行的。
# 搜尋當前目錄下的所有普通文件,並在 -exec 選項中使用 ls -l 命令將它們列出。   
find . -type f -exec ls -l {  }

# 在/logs目錄中搜尋更改時間在5日以前的文件並刪除它們。
find logs -type f -mtime +5 -exec rm {  }

# 列出 /usr/bin 目錄中的鏈接以及它所指向的文件。
find /usr/bin -type l -name "z*" -exec ls -l {}

# 搜索所有零字節文件並將它們移至/tmp/zerobyte文件夾。
find test -type f -size 0 -exec mv {} /tmp/zerobyte
-fls file
返回true;類似-ls但是像-fprint那樣寫入file。
-fprint file
返回true;將文件全名打印到文件file中。如果運行find時file不存在,那麼它將被創建。如果它存在,它將被覆蓋。文件名``/dev/stdout'' 和``/dev/stderr''會作特殊處理;它們分別指的是標準輸出和標準錯誤輸出。
-fprint0 file
返回true;類似-print0但是像-fprint那樣寫入file。
-fprintf file format
返回true;類似-printf但是像-fprint那樣寫入file。
find . -fprintf a.txt '%p\n'
-ok command
類似-exec但是會先向用戶詢問(在標準輸入);如果回應不是以`y'或`Y'起始則不會運行command而是返回false。
# 在當前目錄中搜尋所有文件名以 .conf 結尾、更改時間在5日以上的文件,並刪除它們,只不過在刪除之前先給出提示。
find . -name "*.conf"  -mtime +5 -ok rm {  }
-print
返回true;在標準輸出打印文件全名,然後是一個換行符。
# 搜尋當前用戶家目錄下的所有文件。
find ~ -print

# 將輸出重定向到一個文件。
find / -print > masterfilelist.out
-print0
返回true;在標準輸出打印文件全名,然後是一個null字符。這樣可以使得處理find的輸出的程序可以正確地理解帶有換行符的文件名。
-printf format
返回true;在標準輸出打印format ,解釋`\' escape還有`%'指令。字段寬度和精度可以像C函數`printf'那樣來指定。與-print不同的是, -printf在字符串末端不會添加一個新行。可用的escape和指令如下:
\a警告鈴聲
\b回退
\c立即停止以當前格式輸出,刷新輸出設備。
\f表格結束
\n新行
\r換行
\t水平tab
\v豎直tab
\\輸出自身`\'
\NNNASCII編碼是NNN(八進制)的字符
在一個`\'字符後面使用任何其他字符會被作為普通的字符,因此它們都會被打印出來。
%%輸出自身`%'
%a文件最後一次存取的時間。格式是C函數`ctime'返回值的格式。
%Ak文件最後一次存取的時間。格式以k指定,可以是`@'或者是C函數`strftime'的指令格式。下面列出了k可用的值;有一些並不是在所有系統上都可用,因為不同系統中`strftime'也不同。

  • @ 從Jan. 1, 1970, 00:00 GMT起的秒數

時間字段:
  • H 小時(00..23)
  • I 小時(01..12)
  • k 小時( 0..23)
  • l 小時( 1..12)
  • M 分鐘(00..59)
  • p 本地的AM或者PM
  • r 12小時格式的時間(hh:mm:ss [AP]M)
  • S 秒(00..61)
  • T 24小時格式的時間(hh:mm:ss)
  • X 本地的時間表示方法(H:M:S)
  • Z 時區(例如,EDT),如果不能決定時區就是空


日期字段:
  • a 本地一星期中每天的名稱的縮寫(Sun..Sat)
  • A 本地一星期中每天的全名,可變長度(Sunday..Saturday)
  • b 本地每月的名稱的縮寫(Jan..Dec)
  • B 本地每月的全名,可變長度(January..December)
  • c 本地的日期和時間表示(Sat Nov 04 12:02:33 EST 1989)
  • d 一個月當中的日子(01..31)
  • D 日期(mm/dd/yy)
  • h 與b相同
  • j 一年當中的日子(001..366)
  • m 月份(01..12)
  • U 以星期日作為每週起始,一年當中的星期(00..53)
  • w 一星期當中的日子(0..6)
  • W 以星期一當作每週起始,一年當中的星期(00..53)
  • x 本地的日期表示(mm/dd/yy)
  • y 年份的最後兩位(00..99)
  • Y 年份(1970...)

%b文件大小,以512字節的塊為單位(四捨五入)。
%c文件狀態最後一次修改的時間。格式是C函數`ctime'返回值的格式。
%Ck文件狀態最後一次修改的時間。格式以k指定,類似於%A。
%d文件在目錄樹中的深度;0意味著文件是一個命令行參數。
%f去掉了前面的目錄的文件名(只剩下最後的成分)。
%F文件所在文件系統的類型;這個值可以為-fstype所用。
%g文件的組名,如果組沒有名稱就是數字形式的組ID。
%G文件的數字形式的組ID。
%h文件名的前面的目錄部分(僅除去最後的成分)。
%H據以找到了文件的命令行參數。
%i文件的i結點號(16進制)。
%k文件大小,以1kB的塊為單位(四捨五入)。
%l符號鏈接的目標(如果文件不是一個符號鏈接,那麼結果是空字符串)。
%m文件的權限位(8進制)。
%n文件的硬連接數。
%p文件名。
%P文件名,去掉了據以找到了文件的命令行參數的名稱部分。
%s文件大小,以字節為單位。
%t文件最後一次修改的時間。格式是C函數`ctime'返回值的格式。
%Tk文件最後一次修改的時間。格式以k指定,類似於%A。
%u文件的用戶名,如果用戶沒有名稱就是數字形式的用戶ID。
%U文件的數字形式的用戶ID。
在一個`%'字符後面使用任何其他字符,`%'將被忽略(但是其他字符會被打印出來)。
find . -printf '%p\n'
-prune
如果沒有給出-depth則返回true;不進入當前目錄。如果給出了-depth則返回false;沒有效果。
-ls
返回true;以`ls -dils'格式在標準輸出列出文件。塊以1kB字節為單位計數,除非設置了環境變量POSIXLY_CORRECT,那樣的話會使用512字節的塊。
# 列出 /usr/bin 目錄中的鏈接以及它所指向的文件。
find /usr/bin -type l -name "z*" -ls

運算符OPERATORS

以優先級高低順序排列:
( expr )
強制為優先
! expr
如果expr是false則返回true
# 在 /tmp 目錄中搜尋所有不屬於 panda 的文件。
find /tmp ! -user panda
-not expr
與! expr相同
expr1 expr2
與(隱含的默認運算符);如果expr1為false則不會執行expr2
expr1 -a expr2
與expr1 expr2相同
expr1 -and expr2
與expr1 expr2相同
# 搜尋 /tmp 目錄中大於100000000字節並且在48小時內修改的文件。
find /tmp -size +10000000c -and -mtime +2
expr1 -o expr2
或;如果expr1為true則不會執行expr2
expr1 -or expr2
與expr1 -o expr2相同
# 在 / 目錄下搜尋文件的使用者為 fred 或 george 的文件。
find / -user fred -or -user george

# 要在 /usr/sam 目錄下搜尋不在 dir1 子目錄之內的所有文件。
find /usr/sam -path "/usr/sam/dir1" -prune -or -print

# 避開多個文件夾。
find /usr/sam \( -path /usr/sam/dir1 -or -path /usr/sam/file1 \) -prune -o -print

# 搜尋未列在 /etc/passwd 或 /etc/group 文件中的文件。
find / -nouser -or -nogroup

# 搜尋 SGID 和 SUID 特殊訪問權限的文件。
find / \( -perm -2000 -or -perm -4000 \) -ls

# 在當前目錄下搜尋使用者名稱為(ftp)且權限為(744)的檔案或是群組名稱為(ftp)的檔案
find . \(-user ftp -perm 744\) -or \(-group ftp\)

find /usr/sam \(-path /usr/sam/dir1 -or -path /usr/sam/file1 \) -prune -or -name "temp" -print
expr1 , expr2
列表;expr1和expr2都會被執行。 expr1的值被忽略,列表的值是expr2的值


參考來源:
find - Linux Command - Unix Command
China Linux Forum-中文man page计划

Linux文件查找命令find,xargs详述 | LinuxSir.Org
鳥哥的 Linux 私房菜 -- 檔案與目錄管理
Linux Find 命令精通指南
《find技巧》-“linux命令五分系列”之一 | linux大棚
find指令摘要by yanni
Linux下find命令详解 - 系统管理交流区
Linux find命令详解 - Linux&Unix - 其实我一点也不NB
linux的find查找命令用法 - 不知疲倦的猪

0 回應: