爹地 我找到了! 15個極好的Linux find命令示例

oschina發表於2013-09-27

  前陣子,我們審查了15件實事 find命令的例子(第一部分)。查詢命令可以做很多比只是在尋找基於名稱的檔案 (第2部分)在這篇文章中,讓我們來討論15高階find命令的例子, 包括-根據它訪問,修改或改變的時間查詢檔案,查詢檔案相比之下,執行操作找到的檔案等。

 基於訪問/修改/更改時間查詢檔案

  你可以找到基於以下三個檔案的時間屬性的檔案。

  1. 訪問時間的檔案。檔案訪問時,訪問時間得到更新。
  2. 的檔案的修改時間檔案內容修改時,修改時間得到更新。
  3. 更改檔案的時間。更改時間時,被更新的inode資料的變化

  在下面的例子中,min選項之間的差異和時間選項是引數。

  • 分論點將它的引數為分鐘。例如,60分鐘(1小時)= 60分鐘。
  • 時間引數,將它的引數為24小時。例如,時間2 = 2 * 24小時(2天)。
  • 雖然這樣做的24個小時計算,小數部分都將被忽略,所以25小時為24小時,和47小時取為24小時,僅48小時為48小時。要獲得更清晰的參考atime的部分find命令的手冊頁。

  例1:找到在1個小時內被更改的檔案

  想要通過檔案修改時間找出檔案,可以使用引數 -mmin -mtime。下面是man手冊中有關mmin和mtime的定義。

  • -mmin n 檔案最後一次修改是在n分鐘之內
  • -mtime n 檔案最後一次修改是在 n*24小時之內(譯者注:也就是n天了唄)

  執行下面例子中的命令,將會找到當前目錄以及其子目錄下,最近一次修改時間在1個小時(60分鐘)之內的檔案或目錄

# find . -mmin -60

  同樣的方式,執行下面例子中的命令,將會找到24小時(1天)內修改了的檔案(檔案系統根目錄 / 下)

# find / -mtime -1

  例2:找到1個小時內被訪問過的檔案

  想要通過檔案訪問時間找出檔案,可以使用引數 -amin -atime。下面是man手冊中有關amin和atime的定義。

  • -amin n 檔案最後一次訪問是在n分鐘之內
  • -atime n 檔案最後一次訪問是在 n*24小時之內

  執行下面例子中的命令,將會找到當前目錄以及其子目錄下,最近一次訪問時間在1個小時(60分鐘)之內的檔案或目錄

# find . -amin -60

  同樣的方式,執行下面例子中的命令,將會找到24小時(1天)內被訪問了的檔案(檔案系統根目錄 / 下)

# find / -atime -1

  例3:查詢一個小時內狀態被改變的檔案

  (譯者注:這裡的改變更第1個例子的更改檔案內容時間是不同概念,這裡是更改的是檔案inode的資料,比如檔案的許可權,所屬人等等資訊)

  要查詢檔案的inode的更改時間,使用-cmin和-ctime選項

  • -cmin n  檔案的狀態在n分鐘內被改變
  • -ctime n  檔案狀態在n*24小時內(也就是n天內)被改變

  (譯者注:如果上面的n為-n形式,則表示n分鐘/天之內,n為+n則表示n分鐘/天之前)

  下面的例子在當前目錄和其子目錄下面查詢一個小時內檔案狀態改變的檔案(也就是60分鐘內):

# find . -cmin -60

  同樣的道理,下面的例子在根目錄/及其子目錄下一天內(24小時內)檔案狀態被改變的檔案列表:

# find / -ctime -1

  例4:搜尋僅僅限定於檔案,不顯示資料夾

  上面的例子搜尋出來不僅僅有檔案,還會顯示資料夾。因為當一個檔案被訪問的時候,它所處的資料夾也會被訪問,如果你對資料夾不感興趣,那麼可以使用 -type f 選項

  下面的例子會顯示30分鐘內被修改過的檔案,資料夾不顯示:

# find /etc/sysconfig -amin -30
.
./console
./network-scripts
./i18n
./rhn
./rhn/clientCaps.d
./networking
./networking/profiles
./networking/profiles/default
./networking/profiles/default/resolv.conf
./networking/profiles/default/hosts
./networking/devices
./apm-scripts
[注: 上面的輸出包含了檔案和資料夾]

# find /etc/sysconfig -amin -30 -type f
./i18n
./networking/profiles/default/resolv.conf
./networking/profiles/default/hosts
[注: 上面的輸出僅僅包含檔案]

  例5: 僅僅查詢非隱藏的檔案(不顯示隱藏檔案):

  如果我們查詢的時候不想隱藏檔案也顯示出來,可以使用下面的正則式查詢:

  下面的命令會顯示當前目錄及其子目錄下15分鐘內檔案內容被修改過的檔案,並且只列出非隱藏檔案。也就是說,以.開頭的檔案時不會顯示出來的

# find . -mmin -15 \( ! -regex ".*/\..*" \)

  基於檔案比較的查詢命令

  我們平時通過更別的東西進行比較,會更容易記住一些事情。比如說我想找出在我編輯test檔案之後編輯過的檔案。你可以通過test這個檔案的編輯時間作為比較基準去查詢之後編輯過的檔案:

  例6: 查詢檔案修改時間在某一檔案修改後的檔案:

語法: find -newer FILE

  下面的例子顯示在/etc/passwd修改之後被修改過的檔案。對於系統管理員,想知道你新增了一個使用者後去跟蹤系統的活動狀態是很有幫助的(萬一那新使用者不老實,一上來就亂搞,你很快就知道了  ^_^):

# find -newer /etc/passwd

  例7:查詢檔案訪問時間在某一檔案的修改時間之後的檔案:

# find -newer /etc/passwd

  下面的例子顯示所有在/etc/hosts檔案被修改後被訪問到的檔案。如果你新增了一個主機/埠記錄在/etc/hosts檔案中,你很可能很想知道在那之後有什麼檔案被訪問到了,下面是這個命令:

# find -anewer /etc/hosts

  例8:查詢狀態改變時間在某個檔案修改時間之後的檔案:

語法: find -cnewer FILE

  下面的例子顯示在修改檔案/etc/fstab之後所有檔案狀態改變過的檔案。如果你在/etc/fstab新增了一個掛載點,你很可能像知道那之後那些檔案的狀態發生了改變,這時候你可以使用如下命令:

# find -cnewer /etc/fstab

  在查詢到的檔案列表結果上直接執行命令:

  這之前你已經看到了如果通過find命令去查詢各種條件的檔案列表。如果你對這些find命令還不熟悉,我建議你看完上面的第一部分

  接下來這部分我們向你介紹如果在find命令上執行各種不同的命令,也就是說如何去操作find命令查詢出來的檔案列表。

  我們能在find命令查詢出來的檔名列表上指定任意的操作:

# find <CONDITION to Find files> -exec <OPERATION> \;

  其中的OPERATION可以是任意的命令,下面列舉一下比較常用的:

  •  rm 命令,用於刪除find查詢出來的檔案
  •  mv 命令,用於重新命名查詢出的檔案
  •  ls -l 命令,顯示查詢出的檔案的詳細資訊
  •  md5sum, 對查詢出的檔案進行md5sum運算,可以獲得一個字串,用於檢測檔案內容的合法性
  •  wc 命令,用於統計計算檔案的單詞數量,檔案大小等待
  •  執行任何Unix的shell命令
  •  執行你自己寫的shell指令碼,引數就是每個查詢出來的檔名

  例9:在find命令輸出上使用 ls -l, 列舉出1小時內被編輯過的檔案的詳細資訊

# find -mmin -60
./cron
./secure

# find -mmin -60 -exec ls -l {} \;
-rw-------  1 root root 1028 Jun 21 15:01 ./cron
-rw-------  1 root root 831752 Jun 21 15:42 ./secure

  例10:僅僅在當前檔案系統中搜尋

  系統管理員有時候僅僅想在/掛載的檔案系統分割槽上搜尋,而不想去搜尋其他的掛載分割槽,比如/home/掛載分割槽。如果你有多個分割槽被掛載了,你想在/下搜尋,一般可以按下面的這樣做

  下面這個命令會搜尋根目錄/及其子目錄下所有.log結尾的檔名。如果你有多個分割槽在/下面,那麼這個搜尋會去搜尋所有的被掛載的分割槽:

# find / -name "*.log"

  如果我們使用-xdev選項,那麼僅僅會在在當前檔案系統中搜尋,下面是在xdev的man page上面找到的一段-xdev的定義:

  • -xdev Don’t descend directories on other filesystems.

  下面的命令會在/目錄及其子目錄下搜尋當前檔案系統(也就是/掛載的檔案系統)中所有以.log結尾的檔案,也就是說如果你有多個分割槽掛載在/下面,下面的搜尋不會去搜尋其他的分割槽的(比如/home/)

# find / -xdev -name "*.log"

  例11: 在同一個命令中使用多個{}

  linux手冊說命令中只能使用一個{},不過你可以像下面這樣在同一個命令中使用多個{}

# find -name "*.txt" cp {} {}.bkup \;

  注意,在同一個命令中使用這個{}是可以的,但是在不同的命令裡就不行了,也就是說,如果你想象下面這樣重新命名檔案是行不通的

find -name "*.txt" -exec mv {} `basename {} .htm`.html \;

  例12: 使用多個{}例項

  你可以像下面這樣寫一個shell指令碼去模擬上面那個重新命名的例子

# mv "$1" "`basename "$1" .htm`.html"

  上面的雙引號是為了防止檔名中出現的空格,不加的話會有問題。然後你把這個shell指令碼儲存為mv.sh,你可以像下面這樣使用find命令了

find -name "*.html" -exec ./mv.sh '{}' \;

  所以,任何情況下你在find命令執行中想使用同一個檔名多次的話,先寫一個指令碼,然後在find中通過-exec執行這個指令碼,把檔名引數傳遞進去就行,這是最簡單的辦法

  例13: 將錯誤重定向到/dev/nul

  重定向錯誤輸出一般不是什麼好的想法。一個有經驗的程式設計師懂得在終端顯示錯誤並及時修正它是很重要的。

  尤其是在find命令中重定向錯誤不是個好的實踐。 但是如果你確實不想看到那些煩人的錯誤,想把錯誤都重定向到null裝置中(也就是linux上的黑洞裝置,任何丟進去的東西消失的無影無蹤了)。你可以像下面這樣做

find -name "*.txt" 2>>/dev/null

  有時候這是很有用的。比如,如果你想通過你自己的賬號在/目錄下查詢所有的*.conf檔案,你會得到很多很多的"Permission denied"的錯誤訊息, 就像下面這樣:

$ find / -name "*.conf"
/sbin/generate-modprobe.conf
find: /tmp/orbit-root: Permission denied
find: /tmp/ssh-gccBMp5019: Permission denied
find: /tmp/keyring-5iqiGo: Permission denied
find: /var/log/httpd: Permission denied
find: /var/log/ppp: Permission denied
/boot/grub/grub.conf
find: /var/log/audit: Permission denied
find: /var/log/squid: Permission denied
find: /var/log/samba: Permission denied
find: /var/cache/alchemist/printconf.rpm/wm: Permission denied
[Note: There are two valid *.conf files burned in the "Permission denied" messages]

  你說煩人不?所以,如果你只想看到find命令真實的查詢結果而不是這些"Permission denied"錯誤訊息,你可以將這些錯誤訊息重定向到/dev/null中去

$ find / -name "*.conf" 2>>/dev/null
/sbin/generate-modprobe.conf
/boot/grub/grub.conf
[Note: All the "Permission denied" messages are not displayed]

  例14: 將檔名中的空格換成下劃線

  你從網上下載下來的音訊檔案的檔名很多都帶有空格。但是帶有空格的檔名在linux(類Unix)系統裡面是很不好的。你可以使用find然後後面加上rename命令的替換功能去重新命名這些檔案,將空格轉換成下劃線

  下面顯示怎樣將所有mp3檔案的檔名中的空格換成_

$ find . -type f -iname “*.mp3″ -exec rename “s/ /_/g” {} \;

  例15: 在find結果中同時執行兩條命令

  在find的man page頁面中,下面是一次檔案查詢遍歷中使用兩條命令的語法舉例

  下面的find命令的例子,遍歷檔案系統一次,列出擁有setuid屬性的檔案和目錄,寫入/root/suid.txt檔案, 如果檔案大小超過100M,將其記錄到/root/big.txt中

# find / \( -perm -4000 -fprintf /root/suid.txt '%#m %u %p\n' \) , \
 \( -size +100M -fprintf /root/big.txt '%-10s %p\n' \)

  Find命令示例(第一部分)

  若你喜歡這篇關於find命令的Daddy文章,別忘了看看第一部分的關於find命令的Mommy文章。

  媽咪,我找到了! -- 15個實用的Linux find命令示例

  原文地址:15-practical-unix-linux-find-command-examples-part-2

相關文章