两个不同行号的文件之间的差异

两个不同行号的文件之间的差异

昨天我问过这个问题,并得到了非常棒的答案,在这个网站上提问真是一件乐事。

今天我收到了一个稍微不同的问题

说我有csv1

1,2,3,4
5,6,7,8 --
9,10,11,12
13,14,15 --

并且csv2

1,2,3,4,5 --
20,21,22,23,24
24,25,26,27,28
9,10,11,12,30 --
45,46,47,48,60

我怎样才能只打印前 4 个字段只出现在两个文件之一中的行?换句话说,丢弃每个文件中前四个字段也出现在另一个文件中的行中的所有行。

1,2,3,4
9,10,11,12
20,21,22,23,24
24,25,26,27,28
45,46,47,48,60

请注意,--实际文件中不存在,我添加它们是为了帮助您注意到差异。

到目前为止,我将所有内容加载到 numpy 数组中并比较每个元素,

if a[i] == b[i] and ...

但我想知道是否有更好的方法使用 Linux 工具来实现此目的。

编辑

csv2 中的每一行在 csv1 中都有对应行,并且同一文件中没有重复的行。基本上,我试图从 csv1 中删除 csv2 并输出 csv1 的其余部分。

答案1

以下是一种方法:

$ awk -F, 'NR==FNR{a[$1$2$3$4]++; next}!a[$1$2$3$4]' csv2 csv1
110,12,31,345
1,12,14,55 
12,53,22,10
1,12,32,44 

解释

  • -F,:将字段分隔符设置为 ,。现在,每行的第一个逗号分隔字段将是$1,第二个$2,依此类推。
  • NR==FNR:这是两个 awk 特殊变量。NR 是当前输入行,FNR 是当前文件的行号。只有在读取第一个文件时,这两个值才会相等。
  • NR==FNR{a[$1$2$3$4]++; next}:在读取第一个文件时,将前 4 个字段保存为数组中的键,a并将其值设置为 1。这基本上保存了所有前 4 个字段csv1next确保我们立即跳到下一行,而不处理脚本的其余部分。
  • !a[$1$2$3$4]:awk 的默认操作是打印当前行。因此,如果您使用某个求值为 true 的指令,awk 就会明白它应该打印此行。当未定义!a[ $1$2$3$4]时为 true ,这种情况将发生在的前 4 个字段不存在于 的任何行中的行。因此,此指令将导致打印所有前 4 个字段从未出现过的行(因此它们在数组中的值不是 1)。a[$1$2$3$4]csv1csv2a

相关内容