【问题标题】:Comparing two files column by column in unix shell在unix shell中逐列比较两个文件
【发布时间】:2018-04-04 18:24:45
【问题描述】:

我需要使用 unix shell 逐列比较两个文件,并将差异存储在结果文件中。

例如,如果第 1 个文件的第 1 条记录的第 1 列与第 2 个文件的第 1 条记录的第 1 列匹配,则结果将在结果文件中针对该列存储为“=”,但如果找到列值的任何差异都需要在结果文件中打印。

以下是具体要求。

文件 1:

id  code name  place 
123 abc  Tom   phoenix
345 xyz  Harry seattle
675 kyt  Romil newyork

文件 2:

id  code name  place
123 pkt  Rosy  phoenix
345 xyz  Harry seattle
421 uty  Romil Sanjose

预期的结果文件:

id_1 id_2 code_1 code_2 name_1 name_2 place_1 place_2
=    =      abc  pkt     Tom    Rosy   =       =
=    =      =    =       =      =      =       =
675  421    kyt  uty     =      =      Newyork Sanjose

列是制表符分隔的。

【问题讨论】:

  • 嗨,大卫,感谢您的回复,但这不是我想要的,我的需求完全不同。如果可以,请不胜感激请查看我的需求示例并提供帮助

标签: unix compare


【解决方案1】:

这是相当粗略的编码,但显示了一种使用 awk 发出您想要的内容的方法,并且可以处理相同“架构”的文件 - 而不仅仅是您作为测试提供的特定 4 字段文件。

此方法使用pr 对文件进行简单合并:将每个输入文件的同一行连接起来以将一行呈现给awk 脚本。

awk 脚本假定输入是干净的,并使用这样一个事实:如果变量 n 的值为 2,则脚本中 $n 的值与 $2 相同。因此,脚本使用ij 变量遍历字段对。对于您的测试输入,会处理字段 1 和 5,然后是字段 2 和 6,等等。

只执行非常有限的输入测试:主要是两个输入文件的隐含架构(列/字段的名称)相同。

#!/bin/sh

[ $# -eq 2 ] || { echo "Usage: ${0##*/} <file1> <file2>" 1>&2; exit 1; }
[ -r "$1" -a -r "$2" ] || { echo "$1 or $2: cannot read" 1>&2; exit 1; }

set -e

pr -s -t -m "$@" | \
awk '
  {
    offset = int(NF/2)
    tab = ""
    for (i = 1; i <= offset; i++) {
      j = i + offset
      if (NR == 1) {
        if ($i != $j) {
          printf "\nColumn name mismatch (%s/%s)\n", $i, $j > "/dev/stderr"
          exit
        }
        printf "%s%s_1\t%s_2", tab, $i, $j
      } else if ($i == $j) {
        printf "%s=\t=", tab
      } else {
        printf "%s%s\t%s", tab, $i, $j
      }
      tab = "\t"
    }
    printf "\n"
  }
'

在 Linux 上测试:GNU Awk 4.1.0 和 pr (GNU coreutils) 8.21。

【讨论】:

  • 非常感谢,它确实对我有用,几乎没有变化
  • 真心感谢,对我帮助很大
猜你喜欢
  • 1970-01-01
  • 2016-10-23
  • 2021-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多