首页 > 解决方案 > 如何使用 Bash 对给定列中匹配模式的所有行进行子集化?

问题描述

给定制表符分隔文件:

1    cat      1|1    0|1    0|0    0|0
2    mouse    0|1    1|1    1|1    0|0
3    horse    0|1    0|1    1|1    1|0
4    dog      0|0    0|0    0|0    0|0
5    human    0|0    0|0    0|0    0|0

如何仅在最后三列中对所有具有一个或多个“1 | 1”的行进行子集化?即子集应该返回:

2    mouse    0|1    1|1    1|1    0|0
3    horse    0|1    0|1    1|1    1|0

我需要子集的文件有 2500 列和 100000 行。第 9 到 2500 列包含 0|0 1|1 1|0 或 0|1。如何使用 Bash 在从 9 到 2500 的任何列中对具有一个或多个字符串 1|1 的所有行进行子集化?

我努力了:

awk '/^1|1$/' dummy.vcf > dummy.vcf1

但是,这似乎不起作用。此外,它会考虑所有列,而不是第 9 到 2500 列。

如果有人能够提供帮助,将不胜感激!

谢谢

标签: bashawkterminal

解决方案


这可能是你想要的:

$ awk '{ for (i=4;i<=NF;i++) if ($i == "1|1") { print; next } }' file
2    mouse    0|1    1|1    1|1    0|0
3    horse    0|1    0|1    1|1    1|0

对于您的真实数据,只需将 4 更改为 9:

awk '{ for (i=9;i<=NF;i++) if ($i == "1|1") { print; next } }' file

或给定您的样本数据:

$ awk 'match($0,/^([^\t]+\t){3}.*1\|1/)' file
2       mouse   0|1     1|1     1|1     0|0
3       horse   0|1     0|1     1|1     1|0

并将真实数据的 3 更改为 8。最后一个假设每个字段中只有一个数字,例如|,你不能有。11|10


推荐阅读