栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

从Bash中另一个更大的文件中查找文件行的最快方法

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

从Bash中另一个更大的文件中查找文件行的最快方法

一小段Perl代码解决了该问题。这是采取的方法:

  • 将的行存储
    file1.txt
    在哈希中
  • file2.txt
    逐行读取,解析并提取第二个字段
  • 检查提取的字段是否在哈希中;如果是这样,打印行

这是代码:

#!/usr/bin/perl -wuse strict;if (scalar(@ARGV) != 2) {  printf STDERR "Usage: fgrep.pl smallfile bigfilen";  exit(2);}my ($small_file, $big_file) = ($ARGV[0], $ARGV[1]);my ($small_fp, $big_fp, %small_hash, $field);open($small_fp, "<", $small_file) || die "Can't open $small_file: " . $!;open($big_fp, "<", $big_file)     || die "Can't open $big_file: "   . $!;# store contents of small file in a hashwhile (<$small_fp>) {  chomp;  $small_hash{$_} = undef;}close($small_fp);# loop through big file and find matcheswhile (<$big_fp>) {  # no need for chomp  $field = (split(/|/, $_))[1];  if (defined($field) && exists($small_hash{$field})) {    printf("%s", $_);  }}close($big_fp);exit(0);

我使用file1.txt中的14K行和file2.txt中的130M行运行了上述脚本。它在大约13秒内完成了126K场比赛。这是

time
相同的输出:

real    0m11.694suser    0m11.507ssys 0m0.174s

我运行了@Inian的

awk
代码:

awk 'FNR==NR{hash[$1]; next}{for (i in hash) if (match($0,i)) {print; break}}' file1.txt FS='|' file2.txt

它比Perl解决方案慢得多,因为它使file2.txt中的每一行循环14K次-
这确实很昂贵。它在处理了592K条记录

file2.txt
并产生了40K条匹配的线后中止。这是花了多长时间:

awk: illegal primary in regular expression 24/Nov/2016||592989 at 592989 input record number 675280, file file2.txt source line number 1real    55m5.539suser    54m53.080ssys 0m5.095s

使用@Inian的其他

awk
解决方案可以消除循环问题:

time awk -F '|' 'FNR==NR{hash[$1]; next}$2 in hash' file1.txt FS='|' file2.txt > awk1.outreal    0m39.966suser    0m37.916ssys 0m0.743stime LC_ALL=C awk -F '|' 'FNR==NR{hash[$1]; next}$2 in hash' file1.txt FS='|' file2.txt > awk.outreal    0m41.057suser    0m38.475ssys 0m0.904s

awk
鉴于我们不必编写整个程序来做到这一点,因此在这里给人留下了深刻的印象。

我也运行了@oliv的Python代码。完成这项工作大约花了15个小时,看起来效果不错。构建大型正则表达式的效率不及使用哈希查找的效率。这里的

time
输出:

real    895m14.862suser    806m59.219ssys 1m12.147s

我试图按照建议使用parallel。但是,

fgrep:memory exhausted
即使块大小很小,它也会因错误而失败。


令我惊讶的是,这

fgrep
完全不适合这样做。22小时后我终止了它,并产生了约10万次匹配。 我希望
fgrep
有一个选项可以强制将其内容
-ffile
保留在哈希中,就像Perl代码所做的那样。

我没有检查

join
方法-我不需要排序文件的额外开销。而且,由于
fgrep
性能不佳,我认为
join
这样做不会比Perl代码更好。

感谢大家的关注和回应。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/399040.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号