![根据第一列比较两个文件](https://linux22.com/image/191629/%E6%A0%B9%E6%8D%AE%E7%AC%AC%E4%B8%80%E5%88%97%E6%AF%94%E8%BE%83%E4%B8%A4%E4%B8%AA%E6%96%87%E4%BB%B6.png)
我有两个文件,我想获得一个新文件,其中仅包含第一个文件中的行,但不包含第二个文件中的行。例子:
文件1:
ID firstname lastname
1 John Wilkens
2 Andrea Smith
3 Matthew Freberg
4 Brenda Something
文件2:
ID firstname lastname
1 John Wilkens
2 Andrea Willems
3 Jay Freberg
5 Mike Hart
输出:
ID firstname lastname
4 Brenda Something
我尝试使用 comm,但这也给出了发生更改的行,例如 ID 2 和 3。
你能帮我解决这个问题吗?
答案1
$ awk 'NR==FNR{a[$1]; next} FNR==1 || !($1 in a)' file2 file1
ID firstname lastname
4 Brenda Something
NR==FNR{a[$1]; next}
使用第一列来file2
构建数组键NR
跟踪迄今为止读取的记录总数,FNR
仅记录当前正在读取的文件的记录号。因此NR==FNR
仅适用于第一个文件(假设它不为空)
FNR==1 || !($1 in a)
对于file1
文件,打印标题行或者如果在数组中找不到第一列a
awk -F'\t' '...'
如果您的输入以制表符分隔且awk -F, '...'
以逗号分隔,则使用。
如果第一个文件可以为空,请使用:
awk '!f{a[$1]; next} FNR==1 || !($1 in a)' file2 f=1 file1
这将f
在两个文件之间设置一个标志。
答案2
在 bash 命令行上,您可以执行以下操作。从 file2 中过滤 ID 并在 file1 中查找它们,但仅在行首查找:
$ grep -vf <(< file2 tail -n+2 | grep -Eo '^[^ ]{1,}'|sed 's/.*/^& /') file1
ID firstname lastname
4 Brenda Something