让我们说我有一个非常长的文件与物种及其出现。在我的情况下,我想保留物种中的一些物种: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)。
欢迎任何提示。
答案 0 :(得分:4)
$ 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 '{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的印刷版速记。 (当然,只有在未触发上述next
命令时才会执行此操作。)
使用与方法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 -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