除了在一個目錄結構下查找文件這種基本的操做,你還能夠用find命令實現一些實用的操做,使你的命令行之旅更加簡易。html
本文將介紹15種不管是於新手仍是老鳥都很是有用的Linux find命令。node
首先,在你的home目錄下面建立下面的空文件,來測試下面的find命令示例。linux
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
# vim create_sample_files.sh
touch
MybashProgram.sh
touch
mycprogram.c
touch
MyCProgram.c
touch
Program.c
mkdir
backup
cd
backup
touch
MybashProgram.sh
touch
mycprogram.c
touch
MyCProgram.c
touch
Program.c
# 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
|
這是find命令的一個基本用法。下面的例子展現了用MyCProgram.c做爲查找名在當前目錄及其子目錄中查找文件的方法。程序員
1
2
3
|
# find -name "MyCProgram.c"
.
/backup/MyCProgram
.c
.
/MyCProgram
.c
|
這是find命令的一個基本用法。下面的例子展現了用MyCProgram.c做爲查找名在當前目錄及其子目錄中查找文件的方法,忽略了大小寫。shell
1
2
3
4
5
|
# find -iname "MyCProgram.c"
.
/mycprogram
.c
.
/backup/mycprogram
.c
.
/backup/MyCProgram
.c
.
/MyCProgram
.c
|
在root目錄及其子目錄下查找passwd文件。vim
1
2
3
4
5
|
# find / -name passwd
.
/usr/share/doc/nss_ldap-253/pam
.d
/passwd
.
/usr/bin/passwd
.
/etc/pam
.d
/passwd
.
/etc/passwd
|
在root目錄及其1層深的子目錄中查找passwd. (例如root — level 1, and one sub-directory — level 2)bash
1
2
|
# find -maxdepth 2 -name passwd
.
/etc/passwd
|
在root目錄下及其最大兩層深度的子目錄中查找passwd文件. (例如 root — level 1, and two sub-directories — level 2 and 3 )ssh
1
2
3
4
|
# find / -maxdepth 3 -name passwd
.
/usr/bin/passwd
.
/etc/pam
.d
/passwd
.
/etc/passwd
|
在第二層子目錄和第四層子目錄之間查找passwd文件。socket
1
2
3
|
# find -mindepth 3 -maxdepth 5 -name passwd
.
/usr/bin/passwd
.
/etc/pam
.d
/passwd
|
下面的例子展現了find命令來計算全部不區分大小寫的文件名爲「MyCProgram.c」的文件的MD5驗證和。{}將會被當前文件名取代。測試
1
2
3
4
5
|
find
-iname
"MyCProgram.c"
-
exec
md5sum {} \;
d41d8cd98f00b204e9800998ecf8427e .
/mycprogram
.c
d41d8cd98f00b204e9800998ecf8427e .
/backup/mycprogram
.c
d41d8cd98f00b204e9800998ecf8427e .
/backup/MyCProgram
.c
d41d8cd98f00b204e9800998ecf8427e .
/MyCProgram
.c
|
顯示全部的名字不是MyCProgram.c的文件或者目錄。因爲maxdepth是1,因此只會顯示當前目錄下的文件和目錄。
1
2
3
4
5
6
|
find
-maxdepth 1 -not -iname
"MyCProgram.c"
.
.
/MybashProgram
.sh
.
/create_sample_files
.sh
.
/backup
.
/Program
.c
|
任何一個文件都有一個獨一無二的inode編號,藉此咱們能夠區分文件。建立兩個名字類似的文件,例如一個有空格結尾,一個沒有。
1
2
3
4
5
6
|
touch
"test-file-name"
# touch "test-file-name "
[Note: There is a space at the end]
# ls -1 test*
test
-
file
-name
test
-
file
-name
|
從ls的輸出不能區分哪一個文件有空格結尾。使用選項-i,能夠看到文件的inode編號,藉此能夠區分這兩個文件。
1
2
3
|
ls
-i1
test
*
16187429
test
-
file
-name
16187430
test
-
file
-name
|
你能夠以下面所示在find命令中指定inode編號。在此,find命令用inode編號重命名了一個文件。
1
2
3
4
5
|
find
-inum 16187430 -
exec
mv
{} new-
test
-
file
-name \;
# ls -i1 *test*
16187430 new-
test
-
file
-name
16187429
test
-
file
-name
|
你能夠在你想對那些像上面同樣的糟糕命名的文件作某些操做時使用這一技術。例如,名爲file?.txt的文件名字中有一個特殊字符。若你想執行「rm file?.txt」,下面所示的全部三個文件都會被刪除。因此,採用下面的步驟來刪除」file?.txt」文件。
1
2
|
ls
file1.txt file2.txt
file
?.txt
|
找到每個文件的inode編號。
1
2
3
4
|
ls
-i1
804178 file1.txt
804179 file2.txt
804180
file
?.txt
|
以下所示:?使用inode編號來刪除那些具備特殊符號的文件名。
1
2
3
4
|
find
-inum 804180 -
exec
rm
{} \;
# ls
file1.txt file2.txt
[Note: The
file
with name
"file?.txt"
is now removed]
|
下面的操做時合理的:
此例中,假設目錄包含如下文件。注意這些文件的權限不一樣。
1
2
3
4
5
6
7
8
|
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
|
找到具備組讀權限的文件。使用下面的命令來找到當前目錄下對同組用戶具備讀權限的文件,忽略該文件的其餘權限。
1
2
3
4
5
|
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
|
找到對組用戶具備只讀權限的文件。
1
2
|
find
. -perm g=r -
type
f -
exec
ls
-l {} \;
----r----- 1 root root 0 2009-02-19 20:27 .
/others_can_only_read
|
找到對組用戶具備只讀權限的文件(使用八進制權限形式)。
1
2
|
find
. -perm 040 -
type
f -
exec
ls
-l {} \;
----r----- 1 root root 0 2009-02-19 20:27 .
/others_can_only_read
|
下面命令的輸出文件絕大多數都是鎖定文件盒其餘程序建立的place hoders
1
|
find
~ -empty
|
只列出你home目錄裏的空文件。
1
|
find
. -maxdepth 1 -empty
|
只列出當年目錄下的非隱藏空文件。
1
|
find
. -maxdepth 1 -empty -not -name
".*"
|
下面的命令列出當前目錄及子目錄下的5個最大的文件。這會須要一點時間,取決於命令須要處理的文件數量。
1
|
find
. -
type
f -
exec
ls
-s {} \; |
sort
-n -r |
head
-5
|
方法同查找5個最大的文件相似,區別只是sort的順序是降序。
1
|
find
. -
type
f -
exec
ls
-s {} \; |
sort
-n |
head
-5
|
上面的命令中,極可能你看到的只是空文件(0字節文件)。如此,你可使用下面的命令列出最小的文件,而不是0字節文件。
1
|
find
. -not -empty -
type
f -
exec
ls
-s {} \; |
sort
-n |
head
-5
|
只查找socket文件
1
|
find
. -
type
s
|
查找全部的目錄
1
|
find
. -
type
d
|
查找全部的通常文件
1
|
find
. -
type
f
|
查找全部的隱藏文件
1
|
find
. -
type
f -name
".*"
|
查找全部的隱藏目錄
1
|
find
-
type
d -name
".*"
|
顯示在指定文件以後作出修改的文件。下面的find命令將顯示全部的在ordinary_file以後建立修改的文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
ls
-lrt
total 0
-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
-rw------- 1 root root 0 2009-02-19 20:29 ordinary_file
-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
---------- 1 root root 0 2009-02-19 20:31 no_for_all
# find -newer ordinary_file
.
.
/everybody_read
.
/all_for_all
.
/no_for_all
|
使用-size選項能夠經過文件大小查找文件。
查找比指定文件大的文件
1
|
find
~ -size +100M
|
查找比指定文件小的文件
1
|
find
~ -size -100M
|
查找符合給定大小的文件
1
|
find
~ -size 100M
|
注意: – 指比給定尺寸小,+ 指比給定尺寸大。沒有符號表明和給定尺寸徹底同樣大。
若你發現有些東西頗有用,你能夠給他取別名。而且在任何你但願的地方執行。
經常使用的刪除a.out文件。
1
2
|
alias
rmao=
"find . -iname a.out -exec rm {} \;"
# rmao
|
刪除c程序產生的core文件。
1
2
|
alias
rmc=
"find . -iname core -exec rm {} \;"
# rmc
|
下面的命令刪除大於100M的*.zip文件。
1
|
find
/ -
type
f -name *.zip -size +100M -
exec
rm
-i {} \;"
|
用別名rm100m刪除全部大雨100M的*.tar文件。使用一樣的思想能夠建立rm1g,rm2g,rm5g的一類別名來刪除全部大於1G,2G,5G的文件。
1
2
3
4
5
6
7
8
9
|
alias
rm100m=
"find / -type f -name *.tar -size +100M -exec rm -i {} \;"
# alias rm1g="find / -type f -name *.tar -size +1G -exec rm -i {} \;"
# alias rm2g="find / -type f -name *.tar -size +2G -exec rm -i {} \;"
# alias rm5g="find / -type f -name *.tar -size +5G -exec rm -i {} \;"
# rm100m
# rm1g
# rm2g
# rm5g
|
Find命令示例(第二部分)
前陣子,咱們審查了15件實事 find命令的例子(第一部分)。查找命令能夠作不少比只是在尋找基於名稱的文件 (第2部分)在這篇文章中,讓咱們來討論15高級find命令的例子, 包括-根據它訪問,修改或改變的時間查找文件,查找文件相比之下,執行操做找到的文件等, 拉梅什納塔拉詹:這是個人照片中的可愛的小女兒。她很高興地發如今加州長灘水族館海獅。
你能夠找到基於如下三個文件的時間屬性的文件。
在下面的例子中,min選項之間的差別和時間選項是參數。
想要經過文件修改時間找出文件,可使用參數 -mmin -mtime。下面是man手冊中有關mmin和mtime的定義。
執行下面例子中的命令,將會找到當前目錄以及其子目錄下,最近一次修改時間在1個小時(60分鐘)以內的文件或目錄
1
|
# find . -amin -60
|
一樣的方式,執行下面例子中的命令,將會找到24小時(1天)內被訪問了的文件(文件系統根目錄 / 下)
1
|
# find / -atime -1
|
想要經過文件訪問時間找出文件,可使用參數 -amin -atime。下面是man手冊中有關amin和atime的定義。
執行下面例子中的命令,將會找到當前目錄以及其子目錄下,最近一次訪問時間在1個小時(60分鐘)以內的文件或目錄
1
|
# find . -amin -60
|
一樣的方式,執行下面例子中的命令,將會找到24小時(1天)內被訪問了的文件(文件系統根目錄 / 下)
1
|
# find / -atime -1
|
(譯者注:這裏的改變動第1個例子的更改文件內容時間是不一樣概念,這裏是更改的是文件inode的數據,好比文件的權限,所屬人等等信息)
要查找文件的inode的更改時間,使用-cmin和-ctime選項
(譯者注:若是上面的n爲-n形式,則表示n分鐘/天以內,n爲+n則表示n分鐘/天以前)
下面的例子在當前目錄和其子目錄下面查找一個小時內文件狀態改變的文件(也就是60分鐘內):
1
|
# find . -cmin -60
|
一樣的道理,下面的例子在根目錄/及其子目錄下一天內(24小時內)文件狀態被改變的文件列表:
1
|
# find / -ctime -1
|
例4:搜索僅僅限定於文件,不顯示文件夾
上面的例子搜索出來不只僅有文件,還會顯示文件夾。由於當一個文件被訪問的時候,它所處的文件夾也會被訪問,若是你對文件夾不感興趣,那麼可使用 -type f 選項
下面的例子會顯示30分鐘內被修改過的文件,文件夾不顯示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
# 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分鐘內文件內容被修改過的文件,而且只列出非隱藏文件。也就是說,以.開頭的文件時不會顯示出來的
1
|
# find . -mmin -15 <span class="MathJax_Preview">\( ! -regex ".*/\..*" \)</span><script type="math/tex"> ! -regex ".*/\..*" </script>
|
基於文件比較的查找命令
咱們平時經過更別的東西進行比較,會更容易記住一些事情。好比說我想找出在我編輯test文件以後編輯過的文件。你能夠經過test這個文件的編輯時間做爲比較基準去查找以後編輯過的文件:
例6: 查找文件修改時間在某一文件修改後的文件:
1
|
語法:
find
-newer FILE
|
下面的例子顯示在/etc/passwd修改以後被修改過的文件。對於系統管理員,想知道你新增了一個用戶後去跟蹤系統的活動狀態是頗有幫助的(萬一那新用戶不老實,一上來就亂搞,你很快就知道了 ^_^):
1
|
# find -newer /etc/passwd
|
例7:查找文件訪問時間在某一文件的修改時間以後的文件:
1
|
# find -newer /etc/passwd
|
下面的例子顯示全部在/etc/hosts文件被修改後被訪問到的文件。若是你新增了一個主機/端口記錄在/etc/hosts文件中,你極可能很想知道在那以後有什麼文件被訪問到了,下面是這個命令:
1
|
# find -anewer /etc/hosts
|
例8:查找狀態改變時間在某個文件修改時間以後的文件:
1
|
語法:
find
-cnewer FILE
|
下面的例子顯示在修改文件/etc/fstab以後全部文件狀態改變過的文件。若是你在/etc/fstab新增了一個掛載點,你極可能想知道以後哪些文件的狀態發生了改變,這時候你可使用以下命令:
1
|
# find -cnewer /etc/fstab
|
在查找到的文件列表結果上直接執行命令:
這以前你已經看到了若是經過find命令去查找各類條件的文件列表。若是你對這些find命令還不熟悉,我建議你看完上面的第一部分
接下來這部分咱們向你介紹若是在find命令上執行各類不一樣的命令,也就是說如何去操做find命令查找出來的文件列表。
咱們能在find命令查找出來的文件名列表上指定任意的操做:
1
|
# find <CONDITION to Find files> -exec <OPERATION> \;
|
其中的OPERATION能夠是任意的命令,下面列舉一下比較經常使用的:
1
2
3
4
5
6
7
|
# 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結尾的文件名。若是你有多個分區在/下面,那麼這個搜索會去搜索全部的被掛載的分區:
1
|
# find / -name "*.log"
|
若是咱們使用-xdev選項,那麼僅僅會在在當前文件系統中搜索,下面是在xdev的man page上面找到的一段-xdev的定義:
下面的命令會在/目錄及其子目錄下搜索當前文件系統(也就是/掛載的文件系統)中全部以.log結尾的文件,也就是說若是你有多個分區掛載在/下面,下面的搜索不會去搜索其餘的分區的(好比/home/)
1
|
# find / -xdev -name "*.log"
|
例11: 在同一個命令中使用多個{}
linux手冊說命令中只能使用一個{},不過你能夠像下面這樣在同一個命令中使用多個{}
1
|
# find -name "*.txt" cp {} {}.bkup \;
|
注意,在同一個命令中使用這個{}是能夠的,可是在不一樣的命令裏就不行了,也就是說,若是你想象下面這樣重命名文件是行不通的
1
|
find
-name
"*.txt"
-
exec
mv
{} `
basename
{} .htm`.html \;
|
例12: 使用多個{}實例
你能夠像下面這樣寫一個shell腳本去模擬上面那個重命名的例子
1
|
# mv "$1" "`basename "$1" .htm`.html"
|
上面的雙引號是爲了防止文件名中出現的空格,不加的話會有問題。而後你把這個shell腳本保存爲mv.sh,你能夠像下面這樣使用find命令了
1
|
find
-name
"*.html"
-
exec
.
/mv
.sh
'{}'
\;
|
因此,任何狀況下你在find命令執行中想使用同一個文件名屢次的話,先寫一個腳本,而後在find中經過-exec執行這個腳本,把文件名參數傳遞進去就行,這是最簡單的辦法
例13: 將錯誤重定向到/dev/nul
重定向錯誤輸出通常不是什麼好的想法。一個有經驗的程序員懂得在終端顯示錯誤並及時修正它是很重要的。
尤爲是在find命令中重定向錯誤不是個好的實踐。 可是若是你確實不想看到那些煩人的錯誤,想把錯誤都重定向到null設備中(也就是linux上的黑洞裝置,任何丟進去的東西消失的無影無蹤了)。你能夠像下面這樣作
1
|
find
-name
"*.txt"
2>>
/dev/null
|
有時候這是頗有用的。好比,若是你想經過你本身的帳號在/目錄下查找全部的*.conf文件,你會獲得不少不少的」Permission denied」的錯誤消息, 就像下面這樣:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
$
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]
|
1
2
3
4
|
$
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文件的文件名中的空格換成_
1
|
$
find
. -
type
f -iname 「*.mp3″ -
exec
rename 「s/
/_/g
」 {} \;
|
例15: 在find結果中同時執行兩條命令
在find的man page頁面中,下面是一次文件查找遍歷中使用兩條命令的語法舉例
下面的find命令的例子,遍歷文件系統一次,列出擁有setuid屬性的文件和目錄,寫入/root/suid.txt文件, 若是文件大小超過100M,將其記錄到/root/big.txt中
1
2
|
# find / <span class="MathJax_Preview">\( -perm -4000 -fprintf /root/suid.txt '%#m %u %p\n' \)</span><script type="math/tex"> -perm -4000 -fprintf /root/suid.txt '%#m %u %p\n' </script> , \
<span class=
"MathJax_Preview"
>\( -size +100M -fprintf
/root/big
.txt
'%-10s %p\n'
\)<
/span
><script
type
=
"math/tex"
> -size +100M -fprintf
/root/big
.txt
'%-10s %p\n'
<
/script
>
|
原文地址:http://www.thegeekstuff.com/2009/03/15-practical-linux-find-command-examples/