按列显示 TSV 之间的差异

Show Difference Between TSV by Column

我正在比较两个 TSV 文件,它们是这样生成的包列表:

rpm -qa --qf "%{name}\t%{version}\t%{license}\n" | sort -n > packages

这会生成一个制表符分隔的文件,例如:

alsa-firmware   1.0.28  GPL+ and BSD and GPLv2+ and GPLv2 and LGPLv2+
alsa-lib        1.0.28  LGPLv2+
alsa-tools-firmware     1.0.27  GPLv2+

在另一个系统上我 运行 相同的命令安装了相当多的软件包。我想要第二台服务器上那些附加包的列表。这里棘手的部分是我希望匹配列表不按版本过滤。 Comm 和 Diff 检查整行,我只想按第一个 "column".

过滤

例如,如果第二台服务器有以下包列表:

acl     2.2.51  GPLv2+
alsa-firmware   2.0.28  GPL+ and BSD and GPLv2+ and GPLv2 and LGPLv2+
alsa-lib        2.0.29  LGPLv2+
alsa-tools-firmware     2.0.27  GPLv2+
audit   2.4.1   GPLv2+
binutils        2.23.52.0.1     GPLv3+

我正在寻找一个命令(sed、awk、comm、diff 等)return 第一列的差异 - 在本例中为:

acl     2.2.51  GPLv2+
audit   2.4.1   GPLv2+
binutils        2.23.52.0.1     GPLv3+

请注意,alsa 软件包已更改版本但仍具有相同的软件包名称。

awk,仅匹配两个文件中的第一列

$ awk 'NR==FNR{a[]; next} !( in a)' file1 file2
acl     2.2.51  GPLv2+
audit   2.4.1   GPLv2+
binutils        2.23.52.0.1     GPLv3+


或者将第一列作为搜索模式传递​​给 grep。这假定 file2 中的其他列与搜索词不匹配

$ awk '{print }' file1 | grep -vFf - file2
acl     2.2.51  GPLv2+
audit   2.4.1   GPLv2+
binutils        2.23.52.0.1     GPLv3+


使用 sed,类似于 grep 解决方案,但如果 file1 的第一列包含任何正则表达式元字符

则容易出错
$ sed -f <(sed -E 's|^(\S+).*|//d|' file1) file2
acl     2.2.51  GPLv2+
audit   2.4.1   GPLv2+
binutils        2.23.52.0.1     GPLv3+