linux文件查找命令之find詳解

find命令是linux下最常用的一個命令,它可以根據文件名、文件屬性、類型、大小、時間戳等來實時查找你需要的文件,並可針對搜索結果進行處理。


語法:find [查找路徑] [查找條件] [處理動作]

查找路徑:默認爲當前目錄

查找條件:默認爲指定路徑 下的所有文件

處理動作:默認顯示至屏幕




一、查找條件

1.按文件名稱查找

  • -name “文件名稱“    支持使用globbing字符

[root@test ~]$find /tmp -name 'test*'
/tmp/test.conf
  • -iname  按文件名稱查找,忽略大小寫

[root@test ~]$find /tmp -iname 'test*'
/tmp/test.conf
/tmp/TEST.conf


2.按文件屬性查找

  • -user  或 -group    根據文件的屬主或屬組查找

[root@test ~]$find /tmp/ -user 'mysql'
/tmp/mysql.sock
  • -uid  或 -gid  根據uid或gid查找

[root@test ~]$find /tmp/ -uid 27 -ls
9961483    0 srwxrwxrwx   1 mysql    mysql           0 May 26 13:37 /tmp/mysql.sock
  • nouser  或 nogroup  刪除user時文件屬主則爲uid,也就是nouser,nogroup同理。

[root@test ~]$ find /tmp/ -nouser -ls
9961486    0 -rw-r--r--   1 608      608             0 Jun 20 16:56 /tmp/TEST.conf


3.按組合條件查找

  • 與    -a        默認支持可省略

  • 或    -o

  • 非    -not    !  條件取反

  • -not A -a not B = -not (A -o B)

  • -not A -o not B = -not (A -a B)


4.-type : 根據文件類型查找

  • f :普通文件

[root@test ~]$find /soft/ -maxdepth 1 -type f -ls
2228226  448 -rw-r--r--   1 root     root       458372 Apr  4 03:08 /soft/keepalived-1.2.20.tar.gz
  • d:目錄

[root@test ~]$find /soft/ -maxdepth 1 -type d -ls
2228225    4 drwxr-xr-x   3 root     root         4096 Apr  9 12:41 /soft/
2228227    4 drwxrwxr-x   7 magedu   magedu       4096 Apr  9 12:43 /soft/keepalived-1.2.20
  • l :符號鏈接

[root@test ~]$find /etc -maxdepth 1 -name "redhat*" -type l -ls
4719157    0 lrwxrwxrwx   1 root     root           14 Aug 26  2015 /etc/redhat-release -> centos-release
  • b:塊設備

  • c:字符設備

  • s:套接字文件

  • p:命名管道


5.-size   按文件大小查找

常用單位K,M,G

#查找/data目錄下大小等於3k的文件,-maxdepth 1 表示只進入一級目錄。
#這裏需提一下,find會把大於2k小於3k的文件當作等於3k。
[root@test ~]$find /data -maxdepth 1 -size 3k -ls
6422530    4 -rw-r--r--   1 root     root         2204 Sep 10  2015 /data/mysql_ins_5623.sh

#查找/data目錄下小於4k的文件。如果條件改爲-size -3k,mysql_ins_5623.sh則無法匹配.
#上例說了find把它當成等於3k看待所以不小於3k。
[root@test ~]$find /data -maxdepth 1 -size -4k -ls
6422531    0 -rwxrwxrw-   1 root     root            0 Sep 10  2015 /data/e
6422530    4 -rw-r--r--   1 root     root         2204 Sep 10  2015 /data/mysql_ins_5623.sh

#查找/data目錄下大於3G的文件。
[root@test ~]$find /data -size +3G | xargs ls -alh
-rwxr--r-- 1 root root 3.1G Nov 28  2015 /data/2008R2X64.iso
-rwxr--r-- 1 root root 4.0G Sep 11  2015 /data/CentOS-6.3-x86_64-bin-DVD1.iso


6.根據時間戳查找

以“天”爲單位:

  • -atime      按照文件的訪問時間來查找, -n 查找系統中n天內訪問的文件, +n 查找系統中n天以前訪問的文件。n表示查找正好第n天訪問的文件。

查找/tmp目錄下訪問時間爲3天的文件
[root@test ~]$find /tmp/ -atime 3 -ls
9961484    4 -rw-r--r--   1 root     root            6 Jun 20 17:21 /tmp/test.conf
  • -ctime     按照文件狀態改變時間來查找。 原理同atime

查找/data目錄下3天內文件狀態改變的文件,如文件移動過、更改過屬主屬組等,atime和mtime不會改變只會改變ctime
[root@test53 ~]# find /data/ -ctime -3
/data/script/kvm_install
/data/script/kvm_install/hostinfo
/data/script/phy_install
  • -mtime     按照文件的修改時間來查找文件。原理同atime

查找/chenss目錄下200天前修改過內容的文件並打包
[root@test tmp]$find /chenss/ -mtime +200 > test.list
[root@test chenss]$tar -T test.list -zcvPf test.gar.gz
/chenss/SSHLoginC.py
/chenss/sshexecC.py

以“分鐘”爲單位原理同上

  • -amin  

  • -cmin

  • -mmin


7.-perm 根據權限來查找文件

  • -perm mode 嚴格匹配mode,需和文件權限完全匹配

#查找/tmp目錄下權限爲777的文件
[root@test ~]$find /tmp/ -perm 777 -ls
9961483    0 srwxrwxrwx   1 mysql    mysql           0 May 26 13:37 /tmp/mysql.sock
  • -perm -mode 文件的權限包含mode

[root@test ~]$find /chenss/ -perm -401 -ls
1835009    4 drwxr-xr-x   2 root     root         4096 Jun 21 13:50 /chenss/
1835014    4 -rw-r--r-x   1 root     root          634 Dec 15  2015 /chenss/iptables.sh
  • -perm +mode  文件的權限部分匹配mode

[root@test ~]$find /chenss/ -perm +001 -ls
1835009    4 drwxr-xr-x   2 root     root         4096 Jun 21 13:50 /chenss/
1835014    4 -rw-r--r-x   1 root     root          634 Dec 15  2015 /chenss/iptables.sh

-perm爲+771時你會發現network-analysis.sh也會被匹配,這是因爲u權限7包含rw,g權限包含r,所以用+mode時權限千萬不要用7否則會匹配所有文件。
[root@test ~]$find /chenss/ -perm +771 -ls
1835009    4 drwxr-xr-x   2 root     root         4096 Jun 21 13:50 /chenss/
1835012    4 -rw-------   1 root     root         1483 Dec 10  2015 /chenss/realserver.sh
1837548    4 -rw-r--r--   1 root     root         1567 May 17 23:02 /chenss/swsnmp.sh
1835014    4 -rw-r--r-x   1 root     root          634 Dec 15  2015 /chenss/iptables.sh
1838874   12 -rw-r--r--   1 root     root         9906 Jun 21 13:17 /chenss/network-analysis.sh
  • -perm /mode 等同於-perm +mode

[root@test ~]$find /chenss/ -perm /001 -ls
1835009    4 drwxr-xr-x   2 root     root         4096 Jun 21 13:50 /chenss/
1835014    4 -rw-r--r-x   1 root     root          634 Dec 15  2015 /chenss/iptables.sh


9.-path與-prune  當我們使用find查找某目錄下的文件卻不想查找指定的子目錄時就需要用到它們了。不過需要注意的是當find用了-depth時-prune會失效。-prune在匹配對應-path後的目錄的同時不進入目錄下查找。

用法:

find . -path "./sr*sc" -prune -o print 
#如果查找路徑用的是相對路徑;-path後面則只能跟相對路徑,否則查找結果不會忽略-path後面跟的目錄。

find /tmp -path "/tmp/sr*sc" -prune -o print 
#如果查找路徑用的是絕對路徑-path後面跟的也必須是絕對路徑。
#查找/tmp目錄下以.conf結屬的文件並忽略hsperfdata_nginx和hsperfdata_root目錄
#方法一:
[root@test tmp]$find . -path "./hsperfdata*" -prune -o -name "*.conf"
./test.conf
./hsperfdata_nginx
./TEST.conf
./hsperfdata_root
#命令尾部加-print參數,輸出可忽略-path後面的目錄。
[root@test tmp]$find . -path "./hsperfdata*" -prune -o -name "*.conf" -print
./test.conf
./TEST.conf

#方法二:-path後面跟的路徑千萬不要補全,也就是最後一個“/”不要加,寫成“./hsperfdata_nginx”,
而不是“./hsperfdata_nginx/”,否則結果不是我們期望的。小括號指示括號內的內容留給find去解釋,需轉義。
另要注意的是小括號前後需要加個空格否則會語法錯誤。
[root@test tmp]$find . \( -path "./hsperfdata_nginx" -o -path "./hsperfdata_root" \) -prune -o -name "*.conf" -print
./test.conf
./TEST.conf

#方法三:需要注意的是“,”兩邊都各有一個空格。
[root@test tmp]$ find . -path "./hsperfdata_nginx" -prune , -path "./hsperfdata_root" -prune -o -name "*.conf" -print
./test.conf
./TEST.conf

#方法四:不加-prune也可忽略-path後的目錄,但實際上find是有搜索過"./hsperfdata_*"目錄下的文件,只是因爲-print
位於-o的右側,"./hsperfdata_*“下匹配到的文件無法輸出打印。不建議這種方式。
[root@test tmp]$find . -path "./hsperfdata_*" -o -name "*.conf" -print
./test.conf
./TEST.conf

#方法五:
[root@test tmp]$find . -name "hsperfdata_*" -prune -o -name "*.conf" -print
./test.conf
./TEST.conf

[root@test tmp]$find . -type d -name "hsperfdata_*" -prune -o -name "*.conf" -print 
./test.conf
./TEST.conf

#錯誤用法:查找路徑用的是相對路徑,-path後跟的是絕對路徑,所以查找結果未忽略hsperfdata開頭的目錄。
[root@test tmp]$find . -path "/tmp/hsperfdata*" -prune -o -name "*.conf" -print
./test.conf
./hsperfdata_nginx/abc.conf
./TEST.conf
./hsperfdata_root/abc.conf

說明:
-path "./hsper*" -prune其實是-path "./hsper*" -a -prune的簡寫。-a和-o是短路求值(只要最終的結果已經可以確定
是真或假求值過程便告終止這稱之爲短路求值,short-circuit evaluation。)與 shell的&&和||類似。如果"./hsper*"文
件夾存在,也就是爲真,則求-prune的值,-prune返回真,表示"與“表達式爲真,則忽略”.hsper“文件夾。find將查找當前目錄
下除"hsper*"子目錄下的所有以“.conf”結尾的文件。


二、處理動作

  • -print    默認處理動作打印到屏幕

  • -ls        類似於ls -l,詳細顯示查找到的文件信息,組合查找時默認只顯示查找到的右側靠近ls的部分的信息,需對整個命令引用起來纔可顯示全部結果,本文前部分有很多示例都用了此處理動作。

  • -delete 刪除查找到的文件

[root@test tmp]$find ./hsperfdata_nginx/ -name "*.conf" -delete
  • -exec COMMAND {}  \;     對查找出來的每個文件執行指定命令動作,{}的作用是引用查找到的文件名本身

#查找當前目錄下除"hsperdata_*"子目錄下的以“.conf”結尾的文件。並copy到當前目錄的test子目錄下。
[root@test tmp]$find . -path "./hsperfdata_*" -prune -o -name "*.conf" -exec cp -r {} ./test \;
  • -ok COMMAND {} \;    意義同-exec,不同的是每一個命令動作需確認

備註:一次性查找符合條件的所有文件並一同傳遞給-exec或-ok後面指定的命令,但有些命令不能接受過長的參數此時,使用另一種方式 find | xargs COMMAND  查找文件,按次序一個個傳遞給管道後的命令。


參考文檔

http://stackoverflow.com/questions/1489277/how-to-use-prune-option-of-find-in-sh


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章