首頁 php教程 PHP开发 Find命令實戰

Find命令實戰

Dec 14, 2016 pm 05:28 PM
find命令

話說linux中我最常用的幾個指令就是awk, grep, vim, find,今天我們就來詳細看下find指令的使用 

先來一個簡單例子: 

Shelloo . 表示查找路徑為目前目錄(你也可以指定為其他工程目錄,譬如:~/workspace/login) 

-name 表示搜尋的目標檔名或目錄名(允許使用shell通配符) 


通常上述指令已經能夠完成日常工作需求的80%,但是要想完成另外的20%,你必須再深入了解下find指令... 

現在假設你需要找Test.java 和TEST.java這兩份文件,這時候你該如何做? 
也許你會find . -name "Test.java" 和 find . -name "TEST.java" 執行兩遍 

雖然這樣做結果正確,但是有沒有更簡單的方式呢? 答案,自然有 


Shell程式碼 

find . -name "*.java"  # 递归查找当前目录下所有java文件
登入後複製

發現沒,是不是更優雅了... 

現在我們更進一步,假設我們需要列出~/scripts目錄下所有名為study的文件該如何做呢?


在不了解find命令之前,也許你需要使用shell for循環來遞歸遍歷目錄,然後對每個找到的study判斷是否為文件(有可能是名為study的目錄),若確實是文件則輸出.說了這麼多,這個方式真的是繁瑣異常,但是如果你了解find指令,那麼just one line! 


Shell程式碼 

find . -iname "test.java"   # -iname 与-name参数含义一样,但是忽略大小写
登入後複製

其中-type參數用來指定搜尋的目標類型,f表示普通文件, -type還有其他常用的參數值:f-檔, d-目錄 

現在你已經了解了: 

1.如何指定find搜尋路徑 
2.如何指定find搜尋的目標類型(-type) 
3.要如何指定find搜尋的檔案名稱或目錄名稱(-name / -iname) 

真是不少東西了呢,不過我們要繼續前行,find指令還有很多很有用的參數。

find命令預設是遞歸搜索,它的搜尋演算法應該是我們常說的深度優先遍歷(可以透過指定-depth參數指定採用廣度優先遍歷演算法),但是有時候我們希望僅在當前目錄搜索,或是能夠指定遞迴查找的深度,這時候該如何做呢? 兩個字簡單 

-maxdepth: 指定遞歸查找時的目錄最大深度,若為1,表示僅在當前目錄查找 
-mindepth: 指定遞歸查找時的目錄最小深度 

現在我們看兩個例子(先不要嘗試去運行): 


Shell代碼 

find ~/scripts -type f -name "study"
登入後複製

這兩個命令看似沒有什麼差異,但是運行效果確相差萬裡(特別是當文件很多目錄又非常深時),或者在有的機器上第一種形式根本無法運行,原因為什麼呢? 

因為第一個命令它首先會找出所有java文件,然後再篩選出滿足深度條件的文件,這樣效率非常非常之低,而第二個命令則只是在1-3層目錄下搜尋目標文件,而沒有對整個文件樹進行遞歸遍歷,所以效率很高. 


在我的機器上執行第一種命令,彈出以下警告: 
find: warning: you have specified the -maxdepth option after a non-option argument -name, but options are not positional (-maxdepth affects tests specified before it as well as those specified after tests specified before it as well as those specified after tests). ,你現在你的手上又多了兩把利器-maxdepth 和-mindepth(這個兩個參數,可以提高你的查找效率以及zhuangbility) 

find命令還幾個很有用的參數 
-mtime: 文件內容最後修改時間 
-atime: 檔案最後存取時間 
-ctime: 檔案meta資訊最後修改時間(譬如檔案權限) 

這幾個參數後面要跟一個整數值使用,eg: 

如果你需要查找某個時間段內的修改的文件,這些命令就非常有效了(搞運維的同學應該經常使用) 

說了這麼多參數(-name, -iname, -type, -mindepth , -maxdepth, -mtime等等),想必你對find命令已經有所了解, 
現在我們來看看find命令的一個好基友----xargs 

通常我們需要對查找出來的文件執行某些action,譬如我想查找某個工程目錄下所有使用到StringUtils的java文件,這時候該怎麼辦呢? 

方法1我們可以使用eclipse的搜索,方法2我們可以寫腳本,方法3 just one line ... 



Shell程式碼 

find ~/worksapce/project -name "*.java" | xargs grep "StringUtils"
登入後複製

其中:
find ~/worksapce/project -name "*.java" 将会在家目录下workspace/project中递归查找所有java文件
xargs grep "StringUtils" 表示在文件中(find命令查找出的结果集)查找含有StringUtils字样的文件

也许有人一开始会这样写:find ~/worksapce/project -name "*.java" | grep "StringUtils"
这个命令执行将不会产生任何结果,而原因就是因为没有使用xargs!

现在我们就来说说xargs:xargs是用来把输入流转化为参数的命令(默认把输入流中的空白字符譬如"\n"(换行)替换成" "(空格))

Shell代码

$ cat test   
a  
b  
c  
d  
e  
$ cat test | xargs  
a b c d e
登入後複製

ind命令将查找出的每一个文件名或目录名默认用"\n"分割,然后通过管道 | 作为输入流传递给grep命令,但是grep命令要求输入流必须是参数的形式,譬如:grep "target" file1 file2 所以必须使用xargs重新将输入流转换为参数

说到这里,一些比较严谨的同学也许会说,这样的命令:find ~/worksapce/project -name "*.java" | grep "StringUtils" 是不严谨,不安全的(这里还谈不上不安全,毕竟只是一个grep命令,但要是变成xargs rm -rf 那就危险了),原因就是find命令默认用"\n"分隔结果列表,而xargs会把"\n"转化成空格,所以当文件路径或者文件名含有"\n"这些字符时,就会被错误替换,这时候你在执行个rm -rf ,哦, 卖糕的...

所以我们应该养成好习惯,这样写

Shell代码

find ~/worksapce/project -name "*.java" -print0 | xargs -0 grep "StringUtils"
登入後複製

print0用'\0'(空字符)分隔结果列表,xargs -0 只会将'\0' 替换成空格,这样就不会出现刚才所说的问题了.... 


关于find命令,我就说到这里,赶紧尝试吧... 

更多Find命令实战相关文章请关注PHP中文网!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1665
14
CakePHP 教程
1423
52
Laravel 教程
1321
25
PHP教程
1269
29
C# 教程
1249
24