替代grep

时间:2012-05-07 14:48:55

标签: sed awk grep

我正在寻找2.txt中的一些模式,使用“grep”。然后做一些操纵。 但是,似乎“grep”对于大文本来说太慢了。

for (( i=1; i<=236410; i++ ))
do 
    head -$i 1.txt|tail -1|grep -f - 2.txt|awk '{mul+=$4*$7} END {print $1,$2,$3,mul}'
done > file1

我只是想知道其他选择吗?似乎awk/sed可以做到这一点,但只是不知道如何将变量head -$i 1.txt|tail -1传递给awk或sed

THX

1 个答案:

答案 0 :(得分:1)

假设您的模式文件有236,410行,并假设grep可以处理该输入量,并假设输出文件的顺序不重要,为什么不做呢

grep -f 1.txt 2.txt | awk ... >file1

如果内存有问题,而您的输入是静态字符串,请尝试使用fgrep;它可以处理更多的模式。如果输出的顺序实际上很重要,那么这样的事情应该快得多;

while read line; do
  grep "$line" 2.txt | awk ...
done <1.txt >file1

根据输入的不同,您可能希望使用IFS和/或向read添加一些选项以处理空格,反斜杠等。

如果您只需要236,410条第一行输入,则可以将其更改为

head -n 236410 1.txt |
while read line ...

如果以上都不适合你,这是另一个想法。由于您无论如何都在使用awk进行实际处理,因此您可以将所有处理重构为awk脚本,或者动态创建sed脚本并传递输出那对awk。这有点涉及,并且再次取决于你的模式是什么样的,但这样的事情应该给你一个想法:

sed 's%.*%/&/p%' 1.txt | less

您正在查看的是sed脚本,如果1.txt中的每个模式都匹配,则会打印该脚本。 (如果任何模式包含正斜杠,它将会中断。在简单的情况下,使用不同的分隔符,或者转义模式中的所有斜杠。)现在,您可以将其保存到文件中,或者(如果您的sed可以处理标准输入上的脚本)将其传递给sed的第二个实例:

sed 's%.*%/&/p%' 1.txt | sed -f - -n 2.txt | less

这就是你传递给awk的内容:

sed 's%.*%/&/p%' 1.txt | sed -f - -n 2.txt | awk ... >file1