Board logo

主題: [教學]如何在 Unix 下面,遞迴搜尋一個子目錄所有檔案當中有無特定字串 [打印本頁]

發表人: eric_superman    時間: 2006-6-11 10:35 PM     主題: [教學]如何在 Unix 下面,遞迴搜尋一個子目錄所有檔案當中有無特定字串

在 Windows 下的UltraEdit ,有一個功能 "Find in Files" ,配合 Search Sub Directories 選項打開時,
可遞迴搜尋一個子目錄所有檔案當中有無特定字串,這在許多場合都很有用,
那在 Unix 時,如何搜尋呢,很多人直接想到 grep ,
可惜的是,grep無法遞迴搜尋一個子目錄下的所有檔案,grep 一次只能搜尋一個目錄的一層。
例如  /usr/include 下,通常還有 /usr/include/sys, /usr/include/netinet ,
想要找個  IPPROTO_IPV6 出現在那個 header file ,
用 grep 得試許多個子目錄。

這個時候,就要結合 find 。   find 專門用來找特定檔名的,找到後,要印,要呼叫另一個程式,都可以,

cd /usr/include
find . -name "*.h" -exec grep IPPROTO_IPV6 {} \; -print

以上的find 的參數分四大區:
1)    .    一個點,代表 current directory。
2)   -name "*.h"     -name 是用來指定檔名的條件。加了雙引號是怕 shell 把 *.h 都展開了,那 find 就會錯掉。
3)   -exec grep IPPROTO_IPV6 {} \;      -exec 是執行外部程式,grep IPPROTO_IPV6 大家都很熟, {} 則是 find
       的特殊符號,任何檔名都會代入此處,然後呼叫 grep。     \; 則是另一個 find 的特殊符號 ,代表 -exec 的結束。
4)   -print  ,印出檔名。


輸出結果如下:
  IPPROTO_IPV6   = 41,          /* IPv6-in-IPv4 tunnelling              */
./linux/in.h

    IPPROTO_IPV6 = 41,     /* IPv6 header.  */
#define IPPROTO_IPV6            IPPROTO_IPV6
./netinet/in.h


藍色部分是  find  的 -print 所印出的檔名。
其他的就是 grep 的輸出結果,
兩種輸出是交錯的。

覺得有幫到您的忙的話,就請賞點花吧!

[eric_superman 在  2006-6-13 12:16 AM 作了最後編輯]
發表人: alexanita    時間: 2006-6-12 11:24 AM

以你的例子也可以執行
find /usr/include -name "*.h" -exec grep IPPROTO_IPV6 {} \; -print

find 的功能很強大,接個exec後就可以做很多事情了!

發表人: LSO    時間: 2006-7-12 11:17 PM

我請問一下
grep -r 是否是另一種方式
發表人: eric_superman    時間: 2006-7-13 12:35 AM

唉...我真是老了,
grep 進步到內建 recursive 都不知道!
我學Unix時的 grep ,是沒有 -r 參數的......

Anyway, 當某些功能無內建 recursive 時, find 還是派的上用場....
感謝 LSO 的指正!
發表人: Efain    時間: 2006-7-26 10:35 PM

find + -exec是常見的指令...說真的,還滿好用的...
發表人: innova    時間: 2006-7-27 03:52 AM

新版 grep 有 -r 可以找子目錄下的檔案
舊版 grep 有 -l 列出檔名!

so...

新版:  grep -r -l "KeyWord" Dirs

舊版:  find . -name "*.h" -exec grep -l "KeyWord" {} \;




歡迎光臨 TWed2k (http://twed2k.org/) Powered by Discuz! 4.1.0