find:根據指定條件尋找檔案

來源:互聯網
上載者:User

find 是一個資深的 UNIX 工具。它的功能在於遞迴掃描一個或多個目錄,從中尋找匹配指定條件的檔案。儘管此工具非常有用,但文法卻十分複雜,使用的時候也需要多多練習。最普通的文法是這樣的:

find [選項] [目錄] [條件] [動作]

如果您不指定任何目錄,find 將會尋找目前的目錄。如果您不指定條件,則條件相當於“true”,這樣會把全部檔案都找出來。選項、條件和動作的設定十分繁多,我們在這裡只會提到其中的少數幾個。首先,讓我們來看看著幾個選項:

  • -xdev:不在其它檔案系統的目錄中搜尋。

  • -mindepth <n>:搜尋檔案時至少要深入到指定目錄的第 n 層子目錄。

  • -maxdepth <n>:搜尋檔案時最多深入到指定目錄的第 n 層子目錄。

  • -follow:如果符號連結到目錄,則跟隨符號連結進入。預設情況下,find 不跟隨連結。

  • -daystart:當使用與事件相關的測試時(見下文),將當天的開始時間作為時間戳記,而不是預設值(從目前時間倒退24個小時)。

條件可以是一個或多個原子測試。這是一些有用的測試:

  • -type <檔案類型>:搜尋給定類型的檔案。檔案類型可以是以下之一:f(普通檔案)、d(目錄)、l(符號連結)、s(通訊端)、b(塊模式檔案)、c(字元模式檔案)或p(具名管道)。

  • -name <模式>:尋找檔案名稱與給定模式比對的檔案。使用此選項,模式將被看作shell 全域模式(參見“Shell
    萬用字元”一節)。

  • -iname <模式>:與 -name 類似,但不區分大小寫。

  • -atime <n>、-amin <n>:尋找上次訪問時間在 n 天前(-atime)或 n 分鐘前(-amin) 的檔案。您還可以指定 <+n> 或 <-n>,這代表要搜尋訪問時間在至多或者至少 n 天/分鐘前的檔案。

  • -anewer <檔案>:尋找上次訪問時間晚於檔案的檔案。

  • -ctime <n>、-cmin <n>、-cnewer <file>:與 -atime、-amin 和 -anewer 相同,但比較的是檔案上次修改的時間。

  • -regex <模式>:與 -name 相同,但模式將被看作Regex。

  • -iregex <pattern>:與 -regex 相同,但不區分大小寫。

可供選擇的設定還有很多,請參看 find(1) 中的詳情。要進行組合測試,您可以使用以下格式之一:

  • <c1> -a <c2>:如果 c1 和 c2 都為 true,則結果為 true;-a 是隱含的,也就是說如果您想要同時測試 c1、c2 和 c3 三個條件,只需輸入<c1>
    <c2> <c3>。

  • <c1> -o <c2>:如果 c1 或 c2 中至少有一個是 true,則結果為 true。請注意 -o 的優先順序低於 -a,因此如果您想要匹配滿足條件 c1 或 c2,且滿足 c3 的檔案,您就需要使用括弧,即(
    <c1> -o <c2> ) -a <c3>。您還必須對括弧進行轉碼,否則括弧將被 shell 加以解釋!

  • -not <c1>:測試 c1 的相反結果,因此如果 c1 是 false 的話,-not <c1> 就是 true。

最後,您可以為找到的檔案指定一個動作。最常用的有:

  • -print:僅僅將每個檔案的名稱列印在標準輸出。這是預設動作。

  • -ls:對每個找到的檔案以 ls -ilds 的格式列印在標準輸出上。

  • -exec <命令列>:對每個找到的檔案依次執行命令列。命令列必須以分號(;)結尾,您還必須對其進行轉碼,以防 shell 對其進行解釋;檔案位置以 {} 進行標記。請參看用法的例子。

  • -ok <命令>:與 -exec 相同,但對每個命令都請求使用者確認。

要理解這些選項和參數最好的方法是執行一些例子。現在,您想要在 /usr/share 目錄中尋找全部目錄,只需輸入:

find /usr/share -type d

假設您有 HTTP 伺服器,而您所有的 HTML 檔案都存在 /var/www/html,該目錄也是您的目前的目錄。您想要尋找一個月來沒有編輯過的全部檔案。由於您擁有來自不同作者的頁面,所以有些檔案的副檔名是 html,有些檔案的副檔名是 htm。您想要將這些檔案連結在目錄 /var/www/obsolete 中。您應該輸入[17]:

find \( -name "*.htm" -o -name "*.html" \) -a -ctime -30 \-exec ln {} /var/www/obsolete \;

這個例子看起來有點複雜,我們會進行詳細解釋。這裡所用的條件是:

\( -name "*.htm" -o -name "*.html" \) -a -ctime -30

它所完成的功能正是我們想要的:它會找到檔案名稱以 .htm 或 .html“\( -name "*.htm" -o
-name "*.html" \)” 結尾的檔案,而且(-a) 在最近的三十天內沒有修改過,這大概是一個月(-ctime -30)。請額外注意括弧:這裡的括弧時必需的,因為 -a 的優先順序較高。如果沒有括弧的話,將會找到所有以 .htm 結尾的檔案,以及所有一個月以來沒有修改過且以 .html 結尾的檔案。這顯然不是我們所需要的結果。您還應該注意括弧需要在
shell 中加以轉碼:如果我們寫的是 ( .. ),而不是 \( .. \),那麼 shell 就會對括弧進行解釋,並且試圖在子 shell 中執行 -name "*.htm" -o -name "*.html"……另外一種解決方案是將括弧放在雙引號或單引號中,但是我們更願意在此使用反斜線,因為這裡只有一個字元。

最後,還要對每個檔案執行這個命令:

-exec ln {} /var/www/obsolete \;

這裡,您仍然需要對分號(;)進行轉碼,否則 shell 會將其解釋為命令分隔字元。如果您忘記了進行轉碼,find 將會抱怨說 -exec 缺少一個參數。

最後一個例子:您有一個非常大的目錄(/shared/images),其中包含各種映像。通常,您會使用 touch 命令更新此目錄中名為 stamp 的檔案的時間,這樣您就會有一個可參考的時間。您想要找到比 stamp 檔案新的所有 JPEG 映像,但是您的映像來源各不相同,副檔名有 jpg、jpeg、JPG 以及 JPEG。您還想要不在 old 目錄中搜尋。不僅如此,您還想要將此檔案清單發送給您,而您的使用者名稱是 li_si:

find /shared/images -cnewer     \     /shared/images/stamp       \     -a -iregex ".*\.jpe?g"     \     -a -not -regex ".*/old/.*" \       | mail li_si -s "New images"

當然,如果您每次都要重複輸入的話,這個命令確實沒什麼用。您可能會想要定時執行該命令。要定時運行命令,最簡單的方法就是使用下一節介紹的 cron 精靈。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.