![从另一个文件中删除同名的行](https://linux22.com/image/886815/%E4%BB%8E%E5%8F%A6%E4%B8%80%E4%B8%AA%E6%96%87%E4%BB%B6%E4%B8%AD%E5%88%A0%E9%99%A4%E5%90%8C%E5%90%8D%E7%9A%84%E8%A1%8C.png)
我有以下列表:
NM_000014 3
NM_000015 0
NM_000016 0
NM_000017 0
NM_000018 0
NM_000019 28
NM_000020 0
NM_000021 0
NM_000022 0
NM_000023 0
NM_000024 8
NM_000025 0
NM_000026 0
我还有另一个仅包含第一列的文件:
NM_000031
NM_000032
NM_000033
NM_000034
NM_000022
NM_000035
NM_000036
NM_000037
NM_000023
NM_000038
NM_000039
NM_000040
NM_000041
NM_000042
我想删除第一个文件中被命名为第二个文件的整行。在这种情况下,输出文件将是:
NM_000014 3
NM_000015 0
NM_000016 0
NM_000017 0
NM_000018 0
NM_000019 28
NM_000020 0
NM_000021 0
NM_000024 8
NM_000025 0
NM_000026 0
(删除 NM_000022 和 NM_00023 及其对应值)
谢谢!!
答案1
和awk
:
awk 'NR==FNR {a[$0]; next}; {if ($1 in a) next}; 1' f1.txt f2.txt
输入仅包含一列的文件作为第一个参数,并将要检查(第一列)成员资格的文件作为第二个参数。
NR==FNR {a[$0]; next}
,这里NR==FNR
只对第一个文件成立,然后我们将每一行保存到数组中,a
以便我们可以对第二个文件的第一个参数进行成员资格测试,然后我们转到下一行,而无需对第二个文件进行任何进一步的操作{if ($1 in a) next}; 1
将仅针对第二个文件(要检查的文件)执行,这里我们检查空格分隔的第一个参数是否在数组中a
,如果存在则转到下一行,否则打印整行。
例子:
$ cat f1.txt
NM_000031
NM_000032
NM_000033
NM_000034
NM_000022
NM_000035
NM_000036
NM_000037
NM_000023
NM_000038
NM_000039
NM_000040
NM_000041
NM_000042
$ cat f2.txt
NM_000014 3
NM_000015 0
NM_000016 0
NM_000017 0
NM_000018 0
NM_000019 28
NM_000020 0
NM_000021 0
NM_000022 0
NM_000023 0
NM_000024 8
NM_000025 0
NM_000026 0
$ awk 'NR==FNR {a[$0]; next}; {if ($1 in a) next}; 1' f1.txt f2.txt
NM_000014 3
NM_000015 0
NM_000016 0
NM_000017 0
NM_000018 0
NM_000019 28
NM_000020 0
NM_000021 0
NM_000024 8
NM_000025 0
NM_000026 0
答案2
您还可以使用sed
Bash 循环。
此命令进行修改file1
(创建备份file1.bak
),删除以以下任何行开头的每一行file2
:
while read line ; do sed -i.bak "/$line.*/d" file1 ; done < file2
答案3
这里的 'grep' 命令怎么样:)
grep -Fvf oneColumnedFile listFile > outfile