我有 2 个文件file1
,file2
它们已排序并且包含大部分相似的行。我想显示这两个文件之间添加/修改/抑制的行。
问题在于“修改行”的定义。我希望能够将其作为命令的输入。
例如,给定以下 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
如果您有一组键/值对,并且根据键定义添加、删除和修改的行,那么这并不太难。例如,以awk
with:
作为分隔符:
$ $ 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