天天看點

shell學習之find指令三十個實用示例

首先,在你的home目錄下面建立下面的空檔案,來測試下面的find指令示例。 

# vim create_sample_files.sh

touch MybashProgram.sh

touch mycprogram.c

touch MyCProgram.c

touch Program.c

mkdir backup

cd backup

# chmod +x create_sample_files.sh

# ./create_sample_files.sh

# ls -R

.:

backup                  MybashProgram.sh  MyCProgram.c

create_sample_files.sh  mycprogram.c      Program.c

./backup:

MybashProgram.sh  mycprogram.c  MyCProgram.c  Program.c

1.用檔案名查找(目前目錄查找)

#find -name "Mycprogram.c"

./backup/MyCProgram.c

./MyCProgram.c

2.用檔案名查找檔案,忽略大小寫(目前目錄查找)

#find -iname "Mycprogram.c"

./mycprogram.c

./backup/mycprogram.c

3.使用mindepth和maxdepth限定搜尋指定目錄的深度

a>在root目錄及其子目錄下查找passwd檔案。

#find / -name passwd

./usr/share/doc/nss_ldap-253/pam.d/passwd

./usr/bin/passwd

./etc/pam.d/passwd

./etc/passwd

b>在root目錄及其1層深的子目錄中查找passwd. (例如root — level 1, and one sub-directory — level 2) 

#find -maxdepth 2 -name passwd

c>在root目錄下及其最大兩層深度的子目錄中查找passwd檔案. (例如 root — level 1, and two sub-directories — level 2 and 3 ) 

#find -maxdepth 3 -name passwd

d>在第二層子目錄和第四層子目錄之間查找passwd檔案。 

#find -mindepth 3 -maxdepth 5 -name passwd

4.在find指令查找到的檔案上執行指令

(find指令來計算所有不區分大小寫的檔案名為"MyCProgram.c"的檔案的MD5驗證和。{}将會被目前檔案名取代。)

#find -inamm "MyCProgram.c" -exec md5sum {} \;

d41d8cd98f00b204e9800998ecf8427e  ./mycprogram.c

d41d8cd98f00b204e9800998ecf8427e  ./backup/mycprogram.c

d41d8cd98f00b204e9800998ecf8427e  ./backup/MyCProgram.c

d41d8cd98f00b204e9800998ecf8427e  ./MyCProgram.c

5.相反比對

(顯示所有的名字不是MyCProgram.c的檔案或者目錄。由于maxdepth是1,是以隻會顯示目前目錄下的檔案和目錄。 )

#find -maxdepth 1 -not -iname "MyCProgram.c" 

.

./MybashProgram.sh

./create_sample_files.sh

./backup

./Program.c

6.使用inode編号查找檔案

(任何一個檔案都有一個獨一無二的inode編号,借此我們可以區分檔案。建立兩個名字相似的檔案,例如一個有空格結尾,一個沒有。 )

touch "test-file-name"

# touch "test-file-name "

[Note: There is a space at the end]

# ls -1 test*

test-file-name

從ls的輸出不能區分哪個檔案有空格結尾。使用選項-i,可以看到檔案的inode編号,借此可以區分這兩個檔案。 

ls -i1 test*

16187429 test-file-name

16187430 test-file-name

你可以如下面所示在find指令中指定inode編号。在此,find指令用inode編号重命名了一個檔案。 

#find -inum 16187430 -exec mv {} new-test-file-name \;

#ls -i1 *test*

16187430 new-test-file-name

你可以在你想對那些像上面一樣的糟糕命名的檔案做某些操作時使用這一技術。

例如,名為file?.txt的檔案名字中有一個特殊字元。

若你想執行“rm file?.txt”,下面所示的所有三個檔案都會被删除。是以,采用下面的步驟來删除”file?.txt”檔案。 

ls

file1.txt  file2.txt  file?.txt

找到每一個檔案的inode編号。 

ls -i1

804178 file1.txt

804179 file2.txt

804180 file?.txt

如下所示:?使用inode編号來删除那些具有特殊符号的檔案名。 

#find -inum 804180 -exec rm {} \;

file1.txt  file2.txt

[Note: The file with name "file?.txt" is now removed]

7. 根據檔案權限查找檔案

下面的操作時合理的: 

1. 找到具有指定權限的檔案 

2. 忽略其他權限位,檢查是否和指定權限比對 

3. 根據給定的八進制/符号表達的權限搜尋

此例中,假設目錄包含以下檔案。注意這些檔案的權限不同。 

ls -l

total 0

-rwxrwxrwx 1 root root 0 2009-02-19 20:31 all_for_all

-rw-r--r-- 1 root root 0 2009-02-19 20:30 everybody_read

---------- 1 root root 0 2009-02-19 20:31 no_for_all

-rw------- 1 root root 0 2009-02-19 20:29 ordinary_file

-rw-r----- 1 root root 0 2009-02-19 20:27 others_can_also_read

----r----- 1 root root 0 2009-02-19 20:27 others_can_only_read

找到具有組讀權限的檔案。使用下面的指令來找到目前目錄下對同組使用者具有讀權限的檔案,忽略該檔案的其他權限。

#find . -perm -g=r -type f -exec ls -l {} \;

-rw-r--r-- 1 root root 0 2009-02-19 20:30 ./everybody_read

-rwxrwxrwx 1 root root 0 2009-02-19 20:31 ./all_for_all

----r----- 1 root root 0 2009-02-19 20:27 ./others_can_only_read

-rw-r----- 1 root root 0 2009-02-19 20:27 ./others_can_also_read

找到對組使用者具有隻讀權限的檔案。 

#find . -perm g=r -type f -exec ls -l {} \;

找到對組使用者具有隻讀權限的檔案(使用八進制權限形式)。 

#find . -perm 040 -type f -exec ls -l {} \;

8.找到home目錄及子目錄下所有的空檔案(0位元組檔案)

#find ~ -empty

隻列出你home目錄裡的空檔案。 

#find . -maxdepth 1 -empty

隻列出當年目錄下的非隐藏空檔案。

#find . -maxdepth 1 -emptu -not -name ".*"

9.查找5個最大的檔案

下面的指令列出目前目錄及子目錄下的5個最大的檔案。這會需要一點時間,取決于指令需要處理的檔案數量。

#find . -type f -exec ls -s {} \; | sort -n -r | head -5

10.查找5個最小的檔案

#find . -type f -exec ls -s {} \; | sort -n | head -5

上面的指令中,很可能你看到的隻是空檔案(0位元組檔案)。如此,你可以使用下面的指令列出最小的檔案,而不是0位元組檔案

#find . -not -empty -type f -exec ls -s {} \; | sort -n | head -5

11.使用-type查找指定檔案類型的檔案

隻查找socket檔案

#find . -type -s

查找所有的目錄 

#find . -type d

查找所有的一般檔案 

#find . -type f

查找所有的隐藏檔案 

#find . -type f -name ".*"

查找所有的隐藏目錄 

#find . -type d -name ".*"

12.通過和其他檔案比較修改時間查找檔案

(-newer)顯示在指定檔案之後做出修改的檔案。下面的find指令将顯示所有的在ordinary_file之後建立修改的檔案

ls -lrt

#find -newer ordinary_file

./everybody_read

./all_for_all

./no_for_all

13. 通過檔案大小查找檔案

使用-size選項可以通過檔案大小查找檔案。

查找比指定檔案大的檔案 

find ~ -size +100M

查找比指定檔案小的檔案 

find ~ -size -100M

查找符合給定大小的檔案 

find ~ -size 100M

注意: – 指比給定尺寸小,+ 指比給定尺寸大。沒有符号代表和給定尺寸完全一樣大。

14. 給常用find操作取别名

常用的删除a.out檔案。 

alias rmao="find . -iname a.out -exec rm {} \;"

# rmao

删除c程式産生的core檔案。 

alias rmc="find . -iname core -exec rm {} \;"

# rmc

15. 用find指令删除大型打封包件

下面的指令删除大于100M的*.zip檔案。 

find / -type f -name *.zip -size +100M -exec rm -i {} \;(我)

find / -type f -name *.zip -size +100M -exec rm -i {} \;"

用别名rm100m删除所有大于100M的*.tar檔案。使用同樣的思想可以建立rm1g,rm2g,rm5g的一類别名來删除所有大于1G,2G,5G的檔案。 

#alias rm100m="find / -type f -name *.tar -size +100M -exec rm -i {} \;"

基于通路/修改/更改時間查找檔案

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

? 通路時間的檔案。檔案通路時,通路時間得到更新。 

? 的檔案的修改時間。檔案内容修改時,修改時間得到更新。 

? 更改檔案的時間。更改時間時,被更新的inode資料的變化。

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

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

16.找到在1個小時内被更改的檔案

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

-mmin n 檔案最後一次修改是在n分鐘之内

-mtime n 檔案最後一次修改是在 n*24小時之内(譯者注:也就是n天了呗)

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

#find . -mmin -60 

執行下面例子中的指令,将會找到24小時(1天)内被通路了的檔案(檔案系統根目錄 / 下)

#find / -mtime -1

17.找到1個小時内被通路過的檔案

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

-amin n 檔案最後一次通路是在n分鐘之内

-atime n 檔案最後一次通路是在 n*24小時之内 

執行下面例子中的指令,将會找到目前目錄以及其子目錄下,最近一次通路時間在1個小時(60分鐘)之内的檔案或目錄 

find . -amin -60

同樣的方式,執行下面例子中的指令,将會找到24小時(1天)内被通路了的檔案(檔案系統根目錄 / 下) 

find / -atime -1

18.查找一個小時内狀态被改變的檔案

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

-cmin n  檔案的狀态在n分鐘内被改變

-ctime n  檔案狀态在n*24小時内(也就是n天内)被改變 

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

#find . -cmin -60

同樣的道理,下面的例子在根目錄/及其子目錄下一天内(24小時内)檔案狀态被改變的檔案清單: 

#find / -ctime -1

注:如果上面的n為-n形式,則表示n分鐘/天之内,n為+n則表示n分鐘/天之前

19.搜尋僅僅限定于檔案,不顯示檔案夾

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

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

#find . -mmin -30 -type f

#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

[注: 上面的輸出僅僅包含檔案]

20.僅僅查找非隐藏的檔案(不顯示隐藏檔案)

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

下面的指令會顯示目前目錄及其子目錄下15分鐘内檔案内容被修改過的檔案,并且隻列出非隐藏檔案。也就是說,以.開頭的檔案時不會顯示出來的 

find . -mmin -15 -type f 

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

21.查找檔案修改時間在某一檔案修改後的檔案:

文法: find -newer FILE

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

#find -newer /etc/passwd

22.查找檔案通路時間在某一檔案的修改時間之後的檔案:

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

#find -anewer /etc/hosts

23.查找狀态改變時間在某個檔案修改時間之後的檔案:

文法: find -cnewer FILE

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

#find -cnewer /etc/fstab

我們能在find指令查找出來的檔案名清單上指定任意的操作: 

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

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

 rm 指令,用于删除find查找出來的檔案

 mv 指令,用于重命名查找出的檔案

 ls -l 指令,顯示查找出的檔案的詳細資訊

 md5sum, 對查找出的檔案進行md5sum運算,可以獲得一個字元串,用于檢測檔案内容的合法性

 wc 指令,用于統計計算檔案的單詞數量,檔案大小等待

 執行任何Unix的Shell指令

 執行你自己寫的shell腳本,參數就是每個查找出來的檔案名

24.在find指令輸出上使用 ls -l, 列舉出1小時内被編輯過的檔案的詳細資訊

#find  -mtime -1

./cron

./secure

#find  -mtime -1 -exec ls -l {} \;

-rw-------  1 root root 1028 Jun 21 15:01 ./cron

-rw-------  1 root root 831752 Jun 21 15:42 ./secure

25.僅僅在目前檔案系統中搜尋

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

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

# find / -name "*.log"

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

-xdev Don’t descend directories on other filesystems.

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

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

26.在同一個指令中使用多個{}

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

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

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

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

27. 使用多個{}執行個體

你可以像下面這樣寫一個shell腳本去模拟上面那個重命名的例子 

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

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

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

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

28.将錯誤重定向到/dev/null

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

尤其是在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

[Note: All the "Permission denied" messages are not displayed]

29.将檔案名中的空格換成下劃線

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

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

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

30.在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' \)

轉載位址:http://www.linuxde.net/2013/09/15290.html

本文轉自白羊IT51CTO部落格,原文連結:http://blog.51cto.com/000011211684/1971732,如需轉載請自行聯系原作者

繼續閱讀