过滤文件中与~20,000种组合之一匹配的行的最佳方法是什么?模式是\ tZZZZ \ t其中ZZZZ是我创建的列表中的数字。
我一直在使用:
for i in `cat patterns.txt`;
do
echo "$i
cat large_file.txt | LC_ALL=C grep $i >> matched_lines.txt
done
但似乎很慢。 Python实现也非常慢......
大文件看起来像这样(制表符分隔,3列):
31599 94722 0.0184520931023
31599 33175 0.021944980284
31599 95587 0.0181413842575
31599 93637 0.0184741548464
31599 32411 0.0122635750533
31599 55509 0.0145808169111
答案 0 :(得分:2)
使用GNU sed和bash:
sed -n -f <(sed -n 's|.*|/\t&\t/p|p' patternfile.txt) largefile.txt > result.txt
使用GNU sed,grep和bash:
grep -f <(sed -n 's|.*|\t&\t|p' patternfile.txt) largefile.txt > result.txt
答案 1 :(得分:0)
我也遇到了类似的挑战,我已经确定了数百万个模式,这些模式需要在具有数百万行的文件中进行匹配。在我的案例中,模式是字符串,用于标识搜索文件中所需的记录/行。
特征码文件为〜550万行特征码304MiB。
要搜索的文件是750万行json文档(每行一个json文档),25.1GiB。
因此,根据我的计算,此问题的循环迭代超过41万亿。
7,500,000 * 5,500,000 = 41,250,000,000,000.
我的逻辑是需要在750万行/记录的每一行中搜索550万次搜索。
patterns文件中的模式是唯一的。因此,我有一个想法,每次匹配一个模式,都可以从下一次搜索迭代中将其丢弃,从而减少迭代次数。我试图在python中实现一些东西,但是它太慢了,即使我以后要并行化它。
如果有人可以发表评论以理智地检查我的逻辑/数学,我将不胜感激。
这是我想出的解决方案:
fgrep -f
是一个显而易见的选择,但是〜300 MiB / 5.5百万行的模式导致内核OOM杀手在程序中很早就终止了该过程。
因此,我利用GNU parallels工具按如下方式帮助对特征文件进行分块:
# create 7MB chunks (~100k lines/patterns per chunk), pass each chunk to fgrep -f
time parallel --tmpdir /dev/shm --pipepart --block 7m \
-a ../missing-eventIds-comm-quoted.txt --files 'cat' |
parallel --tmpdir /dev/shm -j4 -L1 --line-buffer '
fgrep -f {} < <(exec 3<> /dev/pts/3; openssl enc -aes-256-cbc -d \
-pass env:SYMETRIC_KEY -in possible-missing-data.gz.enc |
gunzip --stdout | pv -s7510130 --line-mode 2>&3 -N job{#} )
# remove the chunk
rm {}
' | gzip --stdout |
openssl enc -aes-256-cbc -salt -pass env:SYMETRIC_KEY > $matches.gz.enc
--files
的{{1}}选项将输入分块为文件,并在stdout上输出文件名。因此,在第二个parallel
中,parallel
模板令牌被替换为块文件名之一。请注意稍后的{}
来清理大块。在此调用中,rm {}
搜索搜索文件parallel
次,直到处理完所有块为止。
根据我的数据,该方法以750万行文件的46个块迭代完成。我指定了n
4个并行作业,经过的时间约为23分钟。
节点正在使用-j4
的{{1}} vCPU。
这种方法使Intel(R) Xeon(R) Gold 6242 CPU @ 2.80GHz
的内存使用量保持名义。
澄清以下内容:
16 GB RAM
这是流程替换的示例,但是fgrep -f
呢?我有一个< <(exec 3<> /dev/pts/3; openssl enc -aes-256-cbc -d \
-pass env:SYMETRIC_KEY -in possible-missing-data.gz.enc |
gunzip --stdout | pv -s7510130 --line-mode 2>&3 -N job{#} )
在exec 3<>
上运行,我想监视读取搜索文件的进度。因此,我在文件描述符3 tty
上打开了该tty。我利用/dev/pts/3
(pipe viewer)来监视exec 3<> /dev/pts/3
会话中的进度。这为我提供了每个并行过程的进度条和速度检查。这是可选的。