昨天我问了这个问题,得到了很棒的答案,在这个网站上提问真的很开心。
今天我有一个稍微不同的问题
说我有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 的其余部分。
这是一种方法:
解释
-F,
: 设置字段分隔符为,。现在,每行的第一个以逗号分隔的字段将是$1
,第二个$2
以此类推。NR==FNR
:这是两个 awk 特殊变量。NR 是当前输入行,FNR 是当前文件的行号。只有在读取第一个文件时,两者才会相等。NR==FNR{a[$1$2$3$4]++; next}
:在读取第一个文件时,将第一个4个字段保存为数组中的键a
并将其值设置为1。这基本上保存了所有第一个4个字段csv1
。这next
确保我们立即跳到下一行并且不处理脚本的其余部分。!a[$1$2$3$4]
: awk 的默认操作是打印当前行。因此,如果您使用计算结果为 true 的东西,awk 知道它应该打印这一行。!a[ $1$2$3$4]
当a[$1$2$3$4]
未定义csv1
的任何行中不存在第 1 个 4 个字段的行时,为真csv2
。因此,该指令将打印所有前 4 个字段从未出现过的行(因此它们在a
数组中的值不是 1)。