【问题标题】:Comparing two files in BASH line by line逐行比较 BASH 中的两个文件
【发布时间】:2018-04-17 09:13:31
【问题描述】:

我需要制作一个脚本文件来读取两个文件并打印出它们之间的公共行。我知道这两个文件的行数相同,每行只包含一个单词。

文件 1:

Blue
Red
Orange
Green
Yellow
Blue

文件 2:

Blue
Green
Red
Purple
Yellow
Blue

预期输出:

Blue
Yellow
Blue

因此,在示例中,红色和绿色出现在两个文件中,但它们不在每个文件中的同一行,因此它们被忽略。

已尝试使用 awk、grep 和 comm,但无法让它们工作。

试图找到处理时间最短的解决方案。

【问题讨论】:

    标签: string bash awk grep comparison


    【解决方案1】:

    使用 awk:

    awk 'NR == FNR { lines[NR] = $0 } NR != FNR && lines[FNR] == $0 { print }' file1 file2
    

    解释:

    • 读取第一个文件 (NR == FNR) 时,构建行号到值的映射
    • 当读取的不是第一个文件(NR != FNR)时,如果当前行与缓存中对应的行匹配,则打印该行

    这两个文件只读取一次, 并且使用的内存与第一个文件的大小大致相同。

    【讨论】:

      【解决方案2】:

      使用粘贴和 GNU grep。一步一步来。

      paste -d '|' file1 file2
      

      输出:

      蓝色|蓝色 红色|绿色 橙色|红色 绿色|紫色 黄色|黄色 蓝色|蓝色
      paste -d '|' file1 file2 | grep -Po '^(.*)\|+\1$'
      

      输出:

      蓝色|蓝色 黄色|黄色 蓝色|蓝色

      \K:

      paste -d '|' file1 file2 | grep -Po '^(.*)\|+\K\1$'
      

      输出:

      蓝色 黄色的 蓝色

      我假设| 不在您的文件中。

      【讨论】:

      • \K 的接触很好。顺便说一句,如果您已经在使用 PCRE,则可以将其缩短为 paste file1 file2 | grep -Po '(.*)\t\K\1$',因为 paste 默认使用 tab。
      【解决方案3】:

      使用pasteawk

      paste -d'|' file1 file2 | awk -F'|' '$1==$2 {print $1}'
      

      我喜欢使用@Cyrus 中的paste,但我认为使用awk 比较合并的行更容易理解。在这种情况下,-F 负责使用相同的分隔符|,并且将第一位$1 与第二位$2 进行比较非常简单。输出可以是任何一个。

      还假设| 不是输入文件的一部分。可以选择任何其他字符。

      如果输入文件的每一行只包含一个单词,这将更短并且也有效:

      paste file1 file2 | awk '$1==$2 {print $1}'
      

      【讨论】:

        【解决方案4】:

        还有一些方法,

        awk 'FNR==NR{a[FNR,$1];next}(FNR,$1) in a' file1 file2
        

        测试结果:

        $ cat f1
        Blue
        Red
        Orange
        Green
        Yellow
        Blue
        
        $ cat f2
        Blue
        Green
        Red
        Purple
        Yellow
        Blue
        
        $ awk 'FNR==NR{a[FNR,$1];next}(FNR,$1) in a' f1 f2
        Blue
        Yellow
        Blue
        

        【讨论】:

          猜你喜欢
          • 2015-12-02
          • 1970-01-01
          • 1970-01-01
          • 2014-08-24
          • 1970-01-01
          • 2014-11-11
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多