2012-02-24 18 views
2

發現的解決方案:(感謝Zsolt的Botykai和邁克·瑞恩)的Unix腳本來搜索必須包含文本文件的兩個特定的關鍵字

下面的腳本的確切翻譯成awk的一行是:

find /home/data/ -type f -exec awk '/PATTERN1/ {c++} /PATTERN2/ {d++} c>0 && d>0 {print ARGV[1] ; exit 0 } END { if (! c || ! d) {exit 1}}' \{\} \; > assetsToDelete.txt 2>&1 

看到https://stackoverflow.com/a/9442764/356815

原題:

問題很簡單,但我沒有找到一個可能性,爲此創建一個快速腳本。

我有100'000個文本文件,我需要搜索所有這些,滿足兩個條件。

我的腳本看起來像這樣,但它像地獄一樣緩慢......任何更好的主意?

echo Searching for first criteria... 
date 
grep -rl 'PATTERN1' /home/data/assets/ > assets.txt 
file=assets.txt 

echo Now filtering for second criteria 
date 
for i in `cat $file` 
do 
    grep -l 'PATTERN2' $i >> assetsToDelete.txt 
done 
echo DONE 
date 

於是我找了有可能做這樣的事情:

搜索目錄,並篩選出滿足一步到位條件1和條件2中的所有文件。條件通常是模式匹配,但在文件內容的不同行上。

+0

這些模式是否在同一行? – 2012-02-24 17:38:08

+0

不,在不同的行上 – basZero 2012-02-25 07:27:17

回答

7

好與awk你可以這樣做:

awk '/FIRSTPATTERN/ {c++} 
    /SECONDPATTERN/ {d++} 
    c>0 && d>0 {print ARGV[1] ; exit 0 } 
    END { if (! c || ! d) {exit 1}}' INPUTFILE 

現在你可以使用它像:

find /YOUR/PATH -type f -exec \ 
awk '/FIRSTPATTERN/ {c++} 
    /SECONDPATTERN/ {d++} 
    c>0 && d>0 {print ARGV[1] ; exit 0 } 
    END { if (! c || ! d) {exit 1}}' \{\} \; 
+3

返回退出狀態將很有用。類似於:'{exit!c || !d}' – 2012-02-24 18:51:50

+0

@WilliamPursell不錯的提示,謝謝! – 2012-02-24 21:02:58

+0

這是否也在目錄上遞歸地工作?意思是:INPUTFILE可以在這種情況下成爲目錄嗎? – basZero 2012-02-25 07:26:44

1

你可以這樣做......

grep -rl '<ref-date>1960' | xargs grep -l '<source>true</source>' 

..但它不會很快或者其他任何東西,因爲你還在掃描文件兩次。

+0

這一個將讓利用兩個CPU核心,所以會比一個接一個地調用更快 – bobah 2012-02-24 17:51:26

0

的EXAKT一個內膽採用awk做完全一樣的問題腳本如下:

find /home/data/ -type f -exec awk '/PATTERN1/ {c++} /PATTERN2/ {d++} c>0 && d>0 {print ARGV[1] ; exit 0 } END { if (! c || ! d) {exit 1}}' \{\} \; > assetsToDelete.txt 2>&1 

謝謝大家幫我找到這個!

c=0d=0很重要,這樣awk就不會在輸出文件assetsToDelete.txt中多次輸出相同的文件名。

+0

爲什麼你也重定向標準錯誤?這是不對的。 – tripleee 2012-02-26 17:14:59

相關問題