![识别unix中两个文件的差异](https://linux22.com/image/139095/%E8%AF%86%E5%88%ABunix%E4%B8%AD%E4%B8%A4%E4%B8%AA%E6%96%87%E4%BB%B6%E7%9A%84%E5%B7%AE%E5%BC%82.png)
我有2个文件rec1.txt和rec2.txt。
[gpadmin@subh ~]$cat ret1.txt
emcas_fin_bi=324
emcas_fin_drr=3294
emcas_fin_exp=887
emcas_fin_optics=0
emcas_gbo_gs=3077
和
[gpadmin@subh ~]$ cat ret2.txt
emcas_fin_bi=333
emcas_fin_drr=5528
emcas_fin_exp=1134
emcas_fin_optics=0
emcas_fin_revpro=0
emcas_gbo_gs=3897
我提供的比较如下:-
[gpadmin@subh ~]$ diff -y ret1.txt ret2.txt
emcas_fin_bi=324 | emcas_fin_bi=333
emcas_fin_drr=3294 | emcas_fin_drr=5528
emcas_fin_exp=887 | emcas_fin_exp=1134
emcas_fin_optics=0 emcas_fin_optics=0
emcas_gbo_gs=3077 | emcas_fin_revpro=0
> emcas_gbo_gs=3897
我发现上面的输出是错误的,因为 emcas_gbo_gs 很常见,但显示为新词:-
emcas_gbo_gs=3077 | emcas_fin_revpro=0
> emcas_gbo_gs=3897
所需输出:-
emcas_gbo_gs=3077 | emcas_gbo_gs=3897
> emcas_fin_revpro=0
答案1
我假设您有兴趣比较遵循该模式的线条
key=value
并且给定文件中键的顺序并不重要。
由于您的一个文件包含尾随空格,我认为最好先清理输入。以下辅助函数可以执行更多操作。它会丢弃没有=
.它删除前导空白字符和尾随空白字符。它还删除相邻的空白字符=
。
sanitize() { grep '=' "$1" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//; s/[[:space:]]*=[[:space:]]*/=/'; }
另一个函数(使用流程替代,不适合 POSIX)
prepare() { diff <(sanitize "$1") <(sanitize "$2") | grep '^[<|>]' | sort -k 2 | uniq -u -f 1; }
会产生差异。像这样使用它:
prepare ret1.txt ret2.txt
输出将是:
< emcas_fin_bi=324 > emcas_fin_bi=333 < emcas_fin_drr=3294 > emcas_fin_drr=5528 > emcas_fin_exp=1134 < emcas_fin_exp=887 > emcas_fin_revpro=0 < emcas_gbo_gs=3077 > emcas_gbo_gs=3897
这不是你想要的输出,但它相当可解析的。这意味着您几乎可以以任何您想要的方式进一步处理它。例如,您可以使用awk
和column
来获得所需的格式(或至少接近它的格式):
prepare ret1.txt ret2.txt | awk -F '[ =]' '
{ $1 == "<" ? L[$2]=$3 : R[$2]=$3 }
END {
for (key in L) if (key in R) print key"="L[key]"/|/"key"="R[key]
for (key in L) if (! (key in R)) print key"="L[key]"/<"
for (key in R) if (! (key in L)) print " />/"key"="R[key]
}
' | column -s / -t
结果是:
emcas_fin_exp=887 | emcas_fin_exp=1134 emcas_fin_bi=324 | emcas_fin_bi=333 emcas_fin_drr=3294 | emcas_fin_drr=5528 emcas_gbo_gs=3077 | emcas_gbo_gs=3897 > emcas_fin_revpro=0
注意:在 Debian GNU/Linux 9 上测试。