unix - 使用 awk 选择特定单词,同时忽略其他单词

标签 unix awk

假设我有一个很长的文件,其中包含物种及其出现情况。我想保留其中一些发生的物种,就我而言:CHU、NEU、RNE、SCR、TDF。比如我原来的矩阵是:

Species_A; CHU, NEU, TUC, SCR
Species_B; CHU, NEU, RNE, SCR, TDF
Species_C; COR, NEU, SAL, TDF
Species_D; CHU, RNE, SCR, TDF
Species_D; SCR, TDF

我想只保留那些出现过 CHU、NEU、RNE、SCR、TDF 的物种,同时排除其余站点:

Species_B; CHU, NEU, RNE, SCR, TDF
Species_D; CHU, RNE, SCR, TDF
Species_D; SCR, TDF

我认为一种选择可能是:

awk -F “;” '$2/CHU/&&/NEU/&&/RNE/&&/SCR/&&/TDF/{ print}' 文件

但这也包括那些不需要的网站(例如 SAL、TUC)。

欢迎任何提示。

最佳答案

awk方法1:正则表达式

$ awk  '/;([[:blank:],]*(CHU|NEU|RNE|SCR|TDF))+$/' file
Species_B; CHU, NEU, RNE, SCR, TDF
Species_D; CHU, RNE, SCR, TDF
Species_D; SCR, TDF

这仅打印那些与正则表达式 ;([[:blank:],]*(CHU|NEU|RNE|SCR|TDF))+$ 匹配的行。

awk 方法 2:循环

尝试:

$ awk  '{for (i=2;i<=NF;i++) if (!($i~/^(CHU|NEU|RNE|SCR|TDF)/)) next} 1' file
Species_B; CHU, NEU, RNE, SCR, TDF
Species_D; CHU, RNE, SCR, TDF
Species_D; SCR, TDF

它是如何工作的

  • for (i=2;i<=NF;i++) if (!($i~/^(CHU|NEU|RNE|SCR|TDF)/)) next

    这会循环第一个单词之后的所有单词。如果这些单词中的任何一个不是以您批准的 3 字母字符串之一开头,那么我们将跳过其余命令并跳转到 next 重新开始。线。

  • 1

    这是 awk 的 print-the-line 的简写。 (当然,只有当上面的next命令没有被触发时才会执行。)

使用 sed

使用与方法 1 相同的逻辑:

$ sed -En  '/;([[:blank:],]*(CHU|NEU|RNE|SCR|TDF))+$/p' file
Species_B; CHU, NEU, RNE, SCR, TDF
Species_D; CHU, RNE, SCR, TDF
Species_D; SCR, TDF

使用 grep

使用相同的正则表达式逻辑:

$ grep -E  ';([[:blank:],]*(CHU|NEU|RNE|SCR|TDF))+$' file
Species_B; CHU, NEU, RNE, SCR, TDF
Species_D; CHU, RNE, SCR, TDF
Species_D; SCR, TDF

关于unix - 使用 awk 选择特定单词,同时忽略其他单词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48857694/

相关文章:

c - 如何使用 timeval 表示 10 毫秒?

java - 如何在 Java 中为 exec 方法的参数指定文件夹?

linux - 合并排序 gzip 文件

linux - 用于连接两列并在另一个文件中查找连接值的 awk 脚本

linux - AWK 查找两个模式并打印以作为命令执行

awk - 在文本文件的第一行和第二行之间添加一个空行

linux - greping 文件 UNIX.linux bash 中的一个字符。无法通过命令行传递参数(文件名)

unix - 在 UNIX 中从远程服务器下载文件

awk - 如果模式存在于另一列中,则从该列中移除模式

linux - 找到一个模式并修改下一行,而不修改文件中的其他内容。最好是基于 Linux 的命令(sed、awk 等)