如果確定是 source code(如 C/C++)的一部分,這只是一碟小蛋糕:
1 | grep -Prn --color --include=\*.{c,cpp,h} "pattern" |
1 | find . -name "*" - exec sh -c "strings -f {} | grep 'pattern'" \; |
(雖然 grep 有個 --text 選項,但實際測試結果很不理想)
strings 的參數 -f 是顯示檔名,因此假如您想要再串 grep -v 過濾多餘的資料,比方說註解,以下方式是錯的:
1 | find . -name "*" - exec sh -c "strings -f {} | grep 'pattern' | grep -P '^\s*(//|/\*)'" \; |
1 | find . -name "*" - exec sh -c "strings -f {} | grep 'pattern' | grep -P 'filename:^\s*(//|/\*)'" \; |
這個小技巧有兩個不完美的地方:
- 如果原本就是文字檔,丟給 strings 多此一舉,浪費效能
- 行號丟失:不過如果字串放在非文字檔裡,就沒有行號這種問題。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #!/bin/bash #fireinholde.sh IFS=$ '\n' for filename in $( find . -name "*" ) do #is ASCII text? isAscii=$( file $filename | grep -P 'ASCII text$' ) if [ -n "$isAscii" ]; then grep -PHn $1 $filename else #no, you need strings it! result=$(strings $filename | grep -P $1) if [ -n "$result" ]; then for matched in $result do echo "$filename:$matched" done fi fi done |
讚哦!
回覆刪除