使用 Unix 和 Awk 查找一个文件中但不在其他文件中的行

使用 Unix 和 Awk 查找一个文件中但不在其他文件中的行

我有 2 个包含 7 个字段的文件,我想根据 field1 和 field2 打印 file1 中存在但不存在于 file2 中的行。

逻辑:我想打印所有行,其中有特定的column1和column2。并且我们在file2中没有找到column1和column2的集合。示例:“sc2/10 10”您不会在文件 2 中看到该集合,因此它被打印为输出。

文件1:

sc2/80         20      .        A       T         86       F=5;U=4
sc2/60         55      .        G       T         76       F=5;U=4
sc2/10         10      .        G       C         50       F=5;U=4
sc2/68         20      .        T       C         71       F=5;U=4
sc2/24         24      .        T       G         31       F=5;U=4
sc2/11         30      .        A       T         60       F=5;U=4

文件2:

sc2/80         20      .        A       T         30       F=5;U=4 
sc2/60         55      .        T       T         77       F=5;U=4 
sc2/68         20      .        C       C         01       F=5;U=4
sc2/24         29      .        T       G         31       F=5;U=4
sc2/24         19      .        G       G         11       F=5;U=4
sc2/88         89      .        T       G         51       F=5;U=4

预期输出:

sc2/10         10      .        G       C         50       F=5;U=4 
sc2/11         30      .        A       T         60       F=5;U=4 

我将不胜感激你的帮助。

答案1

除非输入很大,否则我会将这些file2对保存到哈希中并使用它来忽略file1.例如:

awk 'FNR == NR { h[$1,$2]; next }; !($1 SUBSEP $2 in h)' file2 file1

输出:

sc2/10         10      .        G       C         50       F=5;U=4         
sc2/24         24      .        T       G         31       F=5;U=4
sc2/11         30      .        A       T         60       F=5;U=4

IIUCsc2/24 24已正确包含在输出中。

解释

  • FNR == NR { h[$1,$2]; next }将对保存到散列$1/$2h(请注意,通过下标访问数组足以分配它),但仅来自第一个输入文件 ( file2)。该next命令跳至下一条记录。
  • ! ($1 SUBSEP $2 in h)仅评估file1并将调用行的默认块不是包含$1/$2对。默认块是{ print $0 }. (注意:避免使用!h[$1,$2](与 相同!h[$1 SUBSEP $2]),因为这会分配它)

上面假设在文件的前两个字段中找不到 的值SUBSEP(通常是字符)。^\

答案2

grep -Fvxf <remove> <all-lines>

  • 适用于未排序的文件
  • 维持秩序
  • 是 POSIX

例子:

cat <<EOF > A
b
1
a
0
01
b
1
EOF

cat <<EOF > B
0
1
EOF

grep -Fvxf B A

输出:

b
a
01
b

解释:

  • -F:使用文字字符串而不是默认的 BRE
  • -x:只考虑与整行匹配的匹配
  • -v: 打印不匹配
  • -f file:从给定文件中获取模式

此方法在预排序文件上比其他方法更慢,因为它更通用。如果速度也很重要,请参阅:https://stackoverflow.com/questions/18204904/fast-way-of-finding-lines-in-one-file-that-are-not-in-another

相关内容