如何删除第 3 列中数字小于 60 的行?

如何删除第 3 列中数字小于 60 的行?

我有一个大文件。我需要删除文件中第 3 列中数字小于 60 的所有行。

示例文件:

35110   Bacteria(100)   Proteobacteria(59)  Alphaproteobacteria(59)
12713   Bacteria(100)   Bacteroidetes(100)  Bacteroidia(100)

期望输出:

12713   Bacteria(100)   Bacteroidetes(100)  Bacteroidia(100)

答案1

不需要 Gawk 扩展:

awk -F '[()]' '$4 >= 60'

这里awk-F通过正则表达式集指定的字段标记器[]:字段由左括号或右括号分隔,因此您会看到第 3 列的数字是第 4 列awk场地。

答案2

您可以使用awk(实际上它必须是 GNU AWK 实现gawk,而不是mawk包含较少功能 - 您可能必须安装它sudo apt install gawk)来完成这项工作:

gawk '{match($3,/\((.+)\)/,m);if(m[1]>=60){print $0}}' MY_FILE

现在尽管承认这一点看起来就像外行人眼中的黑魔法一样,其逻辑很简单:

  • 对于每一行,运行最外层花括号内的内容:
  • 首先,match($3, /\((.+)\)/, m)将正则表达式\((.+)\)(匹配开始和结束圆括号,将括号之间的内容存储为第一个捕获组)与$3已处理输入行的第三列进行匹配,并将生成的匹配数组存储在变量中m
  • 然后,检查条件if (m[1] >= 60),即匹配的第一个捕获组的值(输入中括号之间的内容)是否大于或等于 60。如果为真,则执行{print $0},它只会打印整个当前处理的行。

答案3

这是一个 perl 替代品

perl -alne 'print unless $F[2] =~ /\((\d+)\)$/ && $1 < 60'
  • 匹配并捕获第三个(零索引)字段末尾的带括号的十进制数字序列
  • 如果找到匹配项,则测试捕获组的数值并进行相应打印

前任。

$ perl -alne 'print unless $F[2] =~ /\((\d+)\)$/ && $1 < 60' file
12713   Bacteria(100)   Bacteroidetes(100)  Bacteroidia(100)

请注意,这实现了逻辑“删除文件中第 3 列中数字小于 60 的所有行”正如您的问题所述 - 这与打印行数大于或等于 60 略有不同。


如果您的文件确实是用逗号分隔的(而不是问题中所示的空格分隔),那么您将需要更改分隔符,即

perl -F, -lne 'print unless $F[2] =~ /\((\d+)\)$/ && $1 < 60'

答案4

如果您不想学习/使用命令行工具,您不妨在 LibreOffice Calc 中打开文件并过滤数据(Calc 支持制表符分隔的文件)。

如果你知道的话任何编程语言,那么编写一个小程序来过滤数据就很简单了。

但是如果您需要处理大量数据集,使用 MySQL 这样的 DBMS 会更容易、更快捷、更直观。

相关内容