首页 > 解决方案 > 使用 bash 基于列获取两个 csv 文件之间的差异

问题描述

我有两个 csv 文件a.csvb.csv它们都没有标题,并且一行中的每个值都由\t.

1   apple
2   banana
3   orange
4   pear
apple   0.89
banana  0.57
cherry  0.34

我想减去这两个文件并得到第二列a.csv和第一列之间的差异,b.csv这样a.csv[1] - b.csv[0]会给我另一个文件c.csv看起来像

orange
pear

我不想使用 python 和其他编程语言,而是想使用bash 命令来完成此任务,发现这awk会有所帮助,但不太确定如何编写正确的命令。是另一个类似的问题,但第二个答案用于awk '{print $2,$6-$13}'获取值之间的差异而不是出现。

感谢并感谢您的帮助。

标签: csvawk

解决方案


您可以通过您所指的链接中的史蒂夫的回答轻松地做到这一点,并进行一些调整。不确定其他答案paste是否可以帮助您解决此问题。

从第二个文件创建一个哈希映射,b.csv并再次将其与第二列进行比较a.csv

awk -v FS="\t" 'BEGIN { OFS = FS } FNR == NR { unique[$1]; next } !($2 in unique) { print $2 }' b.csv a.csv

要将输出重定向到新文件,> c.csv请在上一个命令的末尾追加。

将字段分隔符(输入和输出)设置\t为读取制表符分隔的文件。

  1. 如果您必须对多个文件执行操作,这FNR == NR { action; } { action } f1 f2是您在许多命令中发现的通用结构。在提供的第一个文件参数上执行awk之后的块,并且在第二个文件参数上运行下一个块。FNR == NR{..}
  2. 该部分unique[$1]; next创建一个哈希映射unique,其中键作为文件第一列中的值b.csv。内的部分{..}针对文件中的所有列运行。
  3. 在这个文件被完全处理之后,在下一个文件上a.csv,我们这样做!($2 in unique)意味着,标记那些$2在第二个文件中不是unique从第一个文件生成的哈希映射中的键的一部分的行。
  4. 在这些行上仅打印第二列名称{ print $2 }

推荐阅读