代碼1$ tree.|-- 2.log`-- backup `-- 1.log3 directories, 0 files
代碼2$ find -path ./backup./backup
代碼3$ mkdir backup123$ find -path ./backup*find: paths must PRecede expressionUsage: find [path...] [expression]
find
命令報錯:路徑必須先表達。問題分析(引自:http://www.CUOXin.com/baibaluo/archive/2012/08/16/2642403.html):
當目錄下存在多個backup*
,shell命令變成find -path backup backup123
.此時,-name
后面有2個匹配字符,shell報錯。
解決辦法:-path(-name)匹配的字符串已經要用單引號,或者雙引號引住。
代碼4$ find -path './backup*'./backup./backup/1.log./backup123
此時,命令運行正確!
expr1 expr2 -o expr3
等同于 expr1 -a expr2 -o expr3
.與其他語言中的與或非類似。并且是短路求值
代碼5$ find -path ./backup -name '*.log'$
沒有任何返回結果。該語句的含義是:路徑是path,并且名字是以.log結尾的文件。顯然,并不存在。
本語句實際上是想查找,backup下所有的以.log結尾的文件。應是:
find -path './backup*' -name '*.log'
代碼6$ find -path './backup*' -o -name '*.log'./backup./backup/1.log./2.log./backup123
到這個地方,-a
和 -o
的體會已經一目了然了吧。這條命令展示了在backup*下的所有文件和以.log結尾的所有文件。
-prune
的體會貼上這樣的幾條shell
命令,請先自行體會:
代碼7$ find -path './backup*'./backup./backup/1.log./backup123$ find -path './backup*' -prune./backup./backup123
prune
的基本使用-prune
在man中是這么說的
If -depth is not given, true; do not descend the current directory.
If -depth is given, false; no effect.
如果find
語句中存在-depth選項,那么-prune
將會被忽略。否則,-prune
將聲明不展開當前路徑。
這樣在上述的1、2條命令中,由于-prune
選項的存在,致使backup路徑沒有展開。所以1.log沒有在打印列表中。
我們再次做這樣的嘗試:
代碼8$ touch backup123/3.log$ find -path './backup*' -prune./backup./backup123$ find -path './backup*'./backup./backup/1.log./backup123./backup123/3.log
打印的結果和預期是一樣的。
按照上述2 find多條件中說道的那樣,find -path './backup*'
獲得所有backup前綴的文件,然后將結果和-prune
相與
:其實就是判斷前者的結果中是否包含指定路徑的子文件(夾)。
prune
做排除路徑用而一般情況下prune
是這樣使用的
代碼9$ find -path './backup*' -prune -o -name '*.log' -print./2.log
指代的意思是當前路徑除去backup*
文件夾外的所有*.log
文件。
這樣是如愿以償了,但是我們執行一下這樣的一條命令:
代碼10$ find -path './backup*' -o -name '*.log' -print./2.log
返回的結果一模一樣。
這個問題我們暫且擱置不論,繼續來看這樣的2個命令:
代碼11$ find -path './backup*' -prune -o -name '*.log'./backup./2.log./backup123$ find -path './backup*' -o -name '*.log'./backup./backup/1.log./2.log./backup123
2個結果集中只是缺少了./backup/1.log
,-prune
做到的只是一個收縮路徑的功能。
再繼續對比這2個命令和上面兩個命令,缺少的是一個-print
.其實在man里面有這樣的一句話"If no expression is given, the expression '-print' is used."
也就是說-print
是個默認值,那么上面2組命令實際上可以這樣看待:
輸入命令 | 實際命令 |
---|---|
find -path './backup*' -o -name '*.log' | find /( -path './backup*' -o -name '*.log' /) -print |
find -path './backup*' -o -name '*.log' -print | find /( -path './backup*' /) -o /( -name '*.log' -print /) |
代碼9 和 代碼10中的片段可以理解為打印-path './backup*'
為false 、 -name '*.log'
為true的find結果。
而代碼11中的片段則是將-path './backup*' -o -name '*.log'
過濾后所有為true的結果都打印。
那么這樣看來,其實排除路徑其實是將-print
放置到了-o后面作為輸出。而-path './backup*'
執行過,并且返回true,單并未被打印。
那么是不是說,其實,其實,其實-prune
并沒有什么用?
其實可以認為
試想這樣一個場景,在一個java項目中,由于項目龐大,總文件數上萬。想要找到最深2級目錄下所有的java文件。
find . -name "*.java" -maxdepth 2find . -maxdepth 2 -name "*.java"
這樣的2條命令,顯然第二條的執行效率會快?。?!-maxdepth 2
極大程度的進行了一次結果過濾。
那么在寫find命令的時候,應該把能最大程度減小結果集的結果放到前面。
新聞熱點
疑難解答