如何在考虑“修改行”的同时显示两个文件之间的行差异?

如何在考虑“修改行”的同时显示两个文件之间的行差异?

我有 2 个文件file1file2它们已排序并且包含大部分相似的行。我想显示这两个文件之间添加/修改/抑制的行。

问题在于“修改行”的定义。我希望能够将其作为命令的输入。

例如,给定以下 2 个文件(及其原始行格式,即文本后跟冒号和数字,其中 2 个修改行的特征是具有相同的文本但数字不同):

文件1

product1:4
product2:5
product3:6

文件2

product1:7
product3:6
product4:9

我希望输出(任何格式)能够给我:

  • 添加了 1 行:product4:9
  • 1行被删除:product2:5
  • 1行被修改:product1:4变成product1:7
  • (并且 1 行保持不变product3:6:)

我不介意这些是单个命令的输出还是不同命令的输出,以更简单的为准。

以下公式应成立:

(number of lines of file1) + (number of added lines) - (number of suppressed lines) = (number of lines of file2) 

编辑:对于上面的示例,要提供给程序的正则表达式输入是^(.+):[:digit:]+$,以便为每一行提取冒号之前的文本,并使用提取的文本来确定一行是否与另一行相似:

  • 如果给定的 2 行不同,但提取的文本相同,则认为该行已被修改
  • 如果给定的 2 行不同并且提取的文本不同,则认为该行已被删除并添加。

答案1

如果您有一组键/值对,并且根据键定义添加、删除和修改的行,那么这并不太难。例如,以awkwith:作为分隔符:

$ $ awk -F: '{ if(NR==FNR){old[$1]=$2; line[$1]=$0} else{ seen[$1]++; if($1 in old){ if (old[$1] != $2){printf "Modified: %s became %s\n",line[$1],$0}else{print "Same: "$0}}else{print "Added: "$0}}}END{for(key in old){ if(!seen[key]){print "Deleted: "line[key]}}}' file1  file2 
Modified: product1:4 became product1:7
Same: product3:6
Added: product4:9
Deleted: product2:5

这是同样的事情,更容易理解:

awk -F: '
  { 
    if(NR==FNR){ 
        old[$1]=$2; 
        line[$1]=$0
    } 
    else{ 
        seen[$1]++; 
        if($1 in old){ 
            if (old[$1] != $2){
                printf "Modified: %s became %s\n",line[$1],$0
            }
            else{
                print "Same: "$0
            }
        }
        else{
            print "Added: "$0
        }
    }
  }
  END{
    for(key in old){ 
        if(!seen[key]){
            print "Deleted: "line[key]
        }
    }
}' file1  file2 

相关内容