传递正则表达式模式的文件时,Egrep命令挂起

时间:2015-08-05 12:57:32

标签: regex performance shell grep cygwin

注意:我正在使用Cygwin。

将文件传入egrep命令以使用模式的速度非常慢(在第4个字匹配之后,我放弃了超过5分钟)。 我正在尝试运行的命令是:

 cat words.txt | egrep ^"[A-Z]" | egrep -f words9.txt

words.txt 是一个字典(390K字), words9.txt 是我创建的一个文件(36,148字),包含所有小写9个字母的单词 WORD.TXT 。 此命令应该找到任何包含来自 words9.txt 的9个字母单词的10个以上的字母单词。

我是regex和shell命令的新手,所以可能只是这个文件依赖是一种非常低效的方法,(必须为words.txt中的每个单词搜索36148个单词)。有没有更好的解决方法?

2 个答案:

答案 0 :(得分:2)

如果words9.txt没有正则表达式,请尝试使用固定字符串搜索(fgrepgrep -F),而不是使用扩展正则表达式搜索(egrep)。

cat words.txt | egrep "^[A-Z]" | fgrep -f words9.txt

答案 1 :(得分:0)

所以你想改进egrep ^"[A-Z]" words.txt | egrep -f words9.txt

你的words9.txt 是一个正则表达式模式的文件,它只是固定的字符串,因此将其视为(grep -F)通常要快得多,因为@KurzedMetal说。

请注意,如果其内容有近似重复的重叠,您可以通过构建正则表达式手动合并它们,这是您如何做到的:

  • 获取以'inter'开头的所有9个字母的单词列表(使用Unix内置单词dict)
  • awk 'length($0)==9' /usr/share/dict/words
  • 现在说你想把所有以5个字符'inter'开头的9个字母的单词合并成一个正则表达式。首先让我们将它们作为列表:grep "^inter" | paste -sd ',' -给出:
      

    interalar,interally,interarch,interarmy,interaxal,interaxis,跨行,椎间,intercale,intercalm,调解,拦截,城际,interclub,intercome,间作,intercurl,interdash,禁令,interdine,interdome,接口,干扰,交流,特福莱,interfold,interfret,混入,intergilt,共生,interhyal,插,interjoin,interknit,interknot,interknow,交错,互层,interlake,interlard,插页,行间,互连,互借,联锁,循环间,侵犯,插曲,intermaze ,intermeet,intermelt,土葬,相互啮合,intermine,内部构件,内科医生,节间,页间,interpave,interpeal,相互作用,interplea,极间,interpone,夹着,interpour,解释,interrace,interroad,interroom,interrule,中断,intersale,相交,INTERSHOP,intersole,intertalk,interteam,中耕,intertone,intertown,intertwin,因特瓦勒,intervary,intervein,干预,intervert,采访,interweld,interwind,interwish,字间,互通,interwove,interwrap,interzone`

  • 正则表达式将以:inter(a(l(ar|ly)|r(ch|my)|x(al|is))|b(...)|c(...)|...)开头。我们正在实现从L到R的树结构(还有其他方法,但这是显而易见的方式)。
  • 测试它:grep "^inter" words9.txt | egrep '^intera(l(ar|ly)|r(ch|my)|x(al|is))'

      

    interalar     interally     interarch     interarmy     interaxal     interaxis

耶!但是,拥有固定字符串的简单列表可能仍然会更快。此外,这个正则表达式将更难维护,脆弱等。不可能轻松过滤或删除特定的字符串。无论如何,你明白了。 PS我确信有自动化工具可以为这些单词列表构建正则表达式。