0

我正在使用“”在 2.txt 中的 1.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

谢谢

4

1 回答 1

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
于 2012-05-07T15:02:54.763 回答