【问题标题】:sed, awk, grep matching word 2 filessed、awk、grep 匹配单词 2 文件
【发布时间】:2012-06-06 00:46:14
【问题描述】:

希望有人能提供帮助。

我有两个文件。 file-a 看起来像

    bank
    sofa
    table

file-b 是一个“脚本”。 例如,它看起来像:

    abcdfg bank
    kitchen abcdfg
    uhuh sofa :=

我只需要知道file-a 中与file-b 中的任何单词都不匹配的单词并将其打印到file-c

我知道必须在一个文件中执行此操作,但不知道如何将其与另一个文件进行比较。

感谢您的帮助。

【问题讨论】:

    标签: bash sed awk


    【解决方案1】:

    分两步:

    fgrep -f file-a -o file-b > this_words_from_file-a_are_in_file-b
    sort file-a this_words_from_file-a_are_in_file-b | uniq -u 
    

    (首先搜索单词,然后只输出找到的单词,然后sortuniq 过滤掉这些单词。)

    【讨论】:

    【解决方案2】:
    fgrep -of file-a file-b | fgrep -vf - file-a
    

    首先查找 file-a 中所有在 file-b 中的单词,然后再次使用 fgrep 从 file-a 中获取不在该列表中的单词。

    【讨论】:

      【解决方案3】:

      这不会赢得代码高尔夫,但它只对数据进行一次传递,并且不会浪费任何 cpu 时间排序:

      awk '{ for( i=1; i<=NF; i++ ) if( NR==FNR ) w[$i]=1; else delete w[$i] }
           END{ for( i in w ) print i}' file-a file-b > file-c
      

      请注意,加速是巨大的。使用file-afile-b 作为/usr/share/dict/words,这个 awk 解决方案在我的系统上运行了 1.578 秒。 John Lawrence 的 fgrep 解决方案的时间:9.157s。 Zsolt 的 fgrep 的时间 |唯一性:4.951。

      【讨论】:

        【解决方案4】:
        join -1 1 -2 2 -v 1 <(sort file-a) <(sort -k2,2 file-b) > file-c
        

        【讨论】:

          【解决方案5】:
          > fileC; cat fileA | while read ZWORD ; do fgrep -q "$ZWORD" fileB || echo $ZWORD >>fileC; done
          $ cat fileC
          table
          

          线索

          • &gt; fileC 创建一个空文件
          • read 读取fileA 的一行并将其放入变量ZWORD
          • fgrep 不要将 $ZWORD 评估为正则表达式
          • -q很安静
          • || 前面命令失败时执行

          【讨论】:

          • 请注意,这会为每个单词创建一个新的fgrep(子)进程...并在整个文件中一次又一次地为该单词创建一个 itaretes。