解决方案:(感谢Zsolt Botykai和Mike Ryan)
以下脚本到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 :(得分: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}}' \{\} \;
答案 1 :(得分:1)
你可以这样做......
grep -rl '<ref-date>1960' | xargs grep -l '<source>true</source>'
...但它不会快速或任何事情,因为你仍在扫描文件两次。
答案 2 :(得分:0)
与awk
完全相同的exakt单行与问题中的脚本完全相同如下:
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=0
和d=0
非常重要,因此awk不会在输出文件assetsToDelete.txt
中多次打印相同的文件名。