【问题标题】:Comparing 2 files using awk and print if matches使用 awk 比较 2 个文件,如果匹配则打印
【发布时间】:2019-11-11 22:16:31
【问题描述】:

我有两个文件,我想比较 File1 的第 1 列和 File2 的第 10 列,如果匹配则打印。我使用了这个命令,但它只打印 File2 的最后一行。

awk 'BEGIN{FS=OFS="|"}NR==FNR{a[$10]=$0;next}$1 in a {print a[$1],$0}' File2 File1

文件1:

003502|COMMUNICATE|Chat|MEGAMOBILE
003502|COMMUNICATE|News - Headlines|MEGAMOBILE
003502|Entertainment|Promos|MEGAMOBILE
003502|ENTERTAINMENT|Promos|MEGAMOBILE
003502|INFORMATION||MEGAMOBILE

文件2:

1000012640|Libre Aquarius||||By Time||Libre Aquarius subs|1000012640|003502|0|1
1000012587|HULA Aries||||By Time||HULA Aries subs|1000012587|003502|0|1

期望的输出:

1000012587|HULA Aries||||By Time||HULA Aries subs|1000012587|003502|0|1|003502|COMMUNICATE|Chat|MEGAMOBILE
1000012587|HULA Aries||||By Time||HULA Aries subs|1000012587|003502|0|1|003502|COMMUNICATE|News - Headlines|MEGAMOBILE
1000012587|HULA Aries||||By Time||HULA Aries subs|1000012587|003502|0|1|003502|Entertainment|Promos|MEGAMOBILE
1000012587|HULA Aries||||By Time||HULA Aries subs|1000012587|003502|0|1|003502|ENTERTAINMENT|Promos|MEGAMOBILE
1000012587|HULA Aries||||By Time||HULA Aries subs|1000012587|003502|0|1|003502|INFORMATION||MEGAMOBILE
1000012640|Libre Aquarius||||By Time||Libre Aquarius subs|1000012640|003502|0|1|003502|COMMUNICATE|Chat|MEGAMOBILE
1000012640|Libre Aquarius||||By Time||Libre Aquarius subs|1000012640|003502|0|1|003502|COMMUNICATE|News - Headlines|MEGAMOBILE
1000012640|Libre Aquarius||||By Time||Libre Aquarius subs|1000012640|003502|0|1|003502|Entertainment|Promos|MEGAMOBILE
1000012640|Libre Aquarius||||By Time||Libre Aquarius subs|1000012640|003502|0|1|003502|ENTERTAINMENT|Promos|MEGAMOBILE
1000012640|Libre Aquarius||||By Time||Libre Aquarius subs|1000012640|003502|0|1|003502|INFORMATION||MEGAMOBILE

【问题讨论】:

  • 文件 2 包含具有相同键的多个条目。 $10 在列表中出现两次,因此在您的作业 a[$10]=$0 中,您用最后一行覆盖第一行,因为 key ($10) 是相同的。
  • 您的 2 个文件在关键字段中仅共享 1 个值。如果您的实际输入不止于此,则编辑您的示例以显示更多。如果您的真实键值未排序,请确保在您的示例中表示。如果文件之间存在不匹配的键,则也显示它们。

标签: awk


【解决方案1】:

有一个特殊的 bash 命令可以完成这项工作:[join][1]

我建议您使用它而不是 awk,因为它会更节省内存。

正如@EdMorton 所说:

join 要求在 join 字段中对两个输入文件进行排序

join -t"|" -1 10 -2 1 <(sort -t"|" -k10 -n file2) <(sort -t"|" -k1 -n file1)

003502|1000012587|HULA Aries||||By Time||HULA Aries subs|1000012587|0|1|COMMUNICATE|Chat|MEGAMOBILE
003502|1000012587|HULA Aries||||By Time||HULA Aries subs|1000012587|0|1|COMMUNICATE|News - Headlines|MEGAMOBILE
003502|1000012587|HULA Aries||||By Time||HULA Aries subs|1000012587|0|1|ENTERTAINMENT|Promos|MEGAMO
003502|1000012587|HULA Aries||||By Time||HULA Aries subs|1000012587|0|1|Entertainment|Promos|MEGAMOBILE
003502|1000012640|Libre Aquarius||||By Time||Libre Aquarius subs|1000012640|0|1|COMMUNICATE|Chat|MEGAMOBILE
003502|1000012640|Libre Aquarius||||By Time||Libre Aquarius subs|1000012640|0|1|COMMUNICATE|News - Headlines|MEGAMOBILE
003502|1000012640|Libre Aquarius||||By Time||Libre Aquarius subs|1000012640|0|1|ENTERTAINMENT|Promos|MEGAMO
003502|1000012640|Libre Aquarius||||By Time||Libre Aquarius subs|1000012640|0|1|Entertainment|Promos|MEGAMOBILE

【讨论】:

    【解决方案2】:

    由于您有重复的键,您应该跟踪它们。

    awk 'BEGIN{FS=OFS="|"}
         (NR==FNR) { c[$1]++; a[$1,c[$1]]=$0; next }
         ($10 in c) { for(i=1;i<=c[$10];++i) print $0,a[$10,i] }' file1 file2
    

    在上面,数组c 跟踪我们遇到密钥$1 的次数。然后将条目存储在由$1 和序列号c[$1] 索引的数组a 中。在读取file2时,我们检查键$10是否在原始数组c中,如果是,我们按顺序处理所有存储的值。

    此外,由于预期的输出,我们不得不恢复文件顺序。

    【讨论】:

      猜你喜欢
      • 2012-10-18
      • 2016-07-30
      • 2021-06-15
      • 1970-01-01
      • 2020-04-16
      • 2014-08-28
      • 1970-01-01
      • 1970-01-01
      • 2014-02-10
      相关资源
      最近更新 更多