1. find命令簡介
find命令主要用于文件搜索,它的功能非常強大,可以根據不同的標準搜索任何文件,可以在任何位置進行檢索。find命令的主要格式如下:
find path test action
(1)path表示要搜索的路徑,可以同時指定多個路徑,路徑之間以空格隔開:
find /user/bin #搜索/user/bin目錄和子目錄
find / #搜索根目錄及子目錄(實際上就是搜索整個文件系統)
find . #搜索當前目錄
find -root #搜索root用戶的主目錄
find /user/bin /home #搜索/user/bin和/home目錄及它們的子目錄
(2)test表示測試條件,用戶可以指定多個測試條件來查找符合特定標準的文件,條件之間以空格隔開:
find / -type f #搜索的文件類型:f=file d=directory
find / -name "*.txt" #搜索文件名后綴為txt,*為通配符
下面是詳細測試條件表:
條件 | 說明 |
---|---|
-name pattern | 表示包含指定匹配模式的文件名,區分大小寫 |
-type pattern | 指定文件類型 |
-perm mode | 匹配權限被設置為指定mode的文件 |
-user userid | 匹配所有者為指定用戶id的文件< |
-group groupid | 匹配所有者的主組為指定組id的文件 |
-size size | 匹配大小為size的文件 |
-empty | 匹配空文件 |
-amin [-+]n | 文件最后一次訪問時間,-n表示訪問時間為距今n分鐘以內,+n表示訪問時間為距今n分鐘以前,n表示恰好n分鐘 |
-atime [-+]n | 文件最后一次訪問時間,時間單位為天 |
-cmin [-+]n | 文件最后一次狀態改變的時間,時間單位為分鐘 |
-ctime [-+]n | 文件最后一次狀態改變的時間,時間單位為天 |
-mmin [-+]n | 文件最后一次被修改的時間,時間單位為分鐘 |
-mtime [-+]n | 文件最后一次被修改的時間,時間單位為天 |
(3)action表示對find結果執行操作。
|動作|說明|
|------ -----------|:----------------------------|
|-print|默認動作,將結果寫入到標準輸出|
|-fprint file|將結果寫入到文件file|
|-ls|以詳細格式顯示搜索結果|
|-fls file|將詳細格式的結果寫入到文件file|
|-delete|將搜索到的文件刪除<|
|-exec command {} ;|查找并執行命令,{}表示搜索到的文件名|
|-ok command {} ;|查找并執行命令,但是需要用戶確認|
-exec
非常實用,使find命令對搜索結果中的文件執行指定的shell命令,其中command表示shell命令,大括號{}表示搜索結果中的文件名,最后的分號表示命令的結束,分號需要使用反斜線轉義。注意其中的空格。
find ./ -type f -mmin +5 -exec rm {} \;
#找出當前目錄下最后一次在5分鐘以前修改過的文件并刪除。
2.find命令的應用場景
(1) 使用find查找文件中包含指定字符串hello world的txt或者sh文件
find ./ -type f -name "*.sh" -o -name "*.txt" -exec grep -i "hello world" {} \+;
# 注意{}兩端的空格。
# “+”號的作用:可以打印出詳細結果,包括匹配文件名和匹配行內容
# or:邏輯或,在命令中用“-o”表示。本例中表示sh文件或者txt文件都滿足測試條件。
# and:邏輯與,系統默認選項,測試條件之間以空格隔開即可。
# not :邏輯非,在命令中用“!”表示,例如:
find ./ ! -name "*.sh"
那么能不能使用管道來實現呢?例如下面這樣:
find ./ -type f -name "*.sh" -o -name "*.txt" | grep -i "hello world"
#不能得到結果。
這樣無法想要的結果,因為管道會把find的結果作為輸入賦給grep命令,這些結果只是文件名組成的字符串而不是文件的內容。
(2) 搭配xargs解決參數列太長導致溢出的錯誤
參考資料:Xargs用法詳解
在使用find命令的-exec選項處理匹配到的文件時,find命令將所有匹配到的文件一起傳遞給exec執行。但有些系統對能夠傳遞給exec的命令長度有限制,這樣在find命令運行幾分鐘之后,就會出現 溢出錯誤。錯誤信息通常是“參數列太長”或“參數列溢出”。
可以把匹配到的文件傳遞給xargs命令,而xargs命令每次只獲取一部分文件而不是全部,不像-exec選項那樣。這樣它可以先處理最先獲取的一部分文件,然后是下一批,并如此繼續下去。
在使用xargs命令時,究竟是一次獲取所有的參數,還是分批取得參數,以及每一次獲取參數的數目都會根據該命令的選項及系統內核中相應的可調參數來確定。
并且,xargs可以把管道傳來的字符串當作文件去執行,這樣就解決了(1)中的問題。
find ./ -type f -name "*.sh" -o -name "*.txt" | xargs grep -i "hello world"
xargs就是為了能對find搜索到的文件進行操作而編寫的,還有很多其他的用途,例如:
find . -perm -7 -print | xargs chmod o-w
#在當前目錄下查找所有用戶具有讀、寫和執行權限的文件,并收回相應的寫權限。
find / -name *.jpg -type f -print | xargs tar -cvzf images.tar.gz
#查找所有的jpg 文件,并且壓縮它。
find ~ -name ‘*.log’ -print0 | xargs -i -0 rm -f {}
#嘗試用rm刪除太多的文件,你可能得到一個錯誤信息:/bin/rm Argument list too long。用xargs去避免這個問題。
ls *.jpg | xargs -n1 -i cp {} /external-hard-drive/directory
#拷貝所有的圖片文件到一個外部的硬盤驅動。
(3) 統計目錄中全部的文件數量及子目錄數量。
例如以下的shell腳本:
#! /bin/bash
files='find /etc -type f -print | wc -l'
#統計文件數量
directories='find /etc -type d -print | wc -l'
#統計子目錄數量
echo "There are $files regular files in /etc dictionary."
echo "There are $directinories directinories in /etc dictionary."
#輸出統計結果
(4) 設置crontab任務。
工作里很多task都要在服務器上進行,很難清晰的記錄到每一個自己所生成修改的文件,其中的權限問題可能會對其他人產生一些困擾。我們可以設置crontab任務,定時的修改自己文件所屬的組或者文件的權限來控制此問題。例如:
00 05 * * * find /path -user tyroneli -mtime -1 -exec chgrp groupid {} \;
#在每天5點,在path目錄下查找最后修改時間一天之內用戶名為tyroneli的文件或目錄,修改其所屬組。