如何使用awk在每个模式之后进行多重匹配并打印不同数量的行

How to do multiple match and print different number of lines after each pattern using awk

我有一个包含数千行的大文件,如下所示:

>ENST00001234.1
ACGTACGTACGG
TTACCCAGTACG
ATCGCATTCAGC
>ENST00002235.4
TTACGCAT
TAGGCCAG
>ENST00005546.9
TTTATCGC
TTAGGGTAT

我想grep特定的ids(在>符号之后),例如,ENST00001234.1然后想在匹配之后得到行直到下一个>[不管数字是多少线]。我想用这种方式一次grep大约63个id。

如果我 grep ENST00001234.1ENST00005546.9 ids,理想的输出应该是:

>ENST00001234.1
ACGTACGTACGG
TTACCCAGTACG
ATCGCATTCAGC
>ENST00005546.9
TTTATCGC
TTAGGGTAT

我尝试了 awk '/ENST00001234.1/ENST00005546.9/{print}' 但没有用。

您可以设置>作为记录分隔符:

$ awk -F'\n' -v RS='>' -v ORS= '=="ENST00001234.1"{print RS [=10=]}' ip.txt
>ENST00001234.1
ACGTACGTACGG
TTACCCAGTACG
ATCGCATTCAGC
  • -F'\n' 以便更轻松地将搜索词与第一行进行比较
  • -v RS='>' 设置 > 作为输入记录分隔符
  • -v ORS=清除输出记录分隔符,否则你会在输出中得到额外的换行符
  • =="ENST00001234.1" 这将进行字符串比较并匹配整个第一行,否则你将不得不转义像 . 这样的正则表达式元字符并添加锚点
  • print RS [=19=]如果找到匹配,打印>和记录内容


如果要匹配多个搜索词,请将它们放在一个文件中:

$ cat f1
ENST00001234.1
ENST00005546.9

$ awk 'BEGIN{FS="\n"; ORS=""}
       NR==FNR{a[[=11=]]; next}
        in a{print RS [=11=]}' f1 RS='>' ip.txt
>ENST00001234.1
ACGTACGTACGG
TTACCCAGTACG
ATCGCATTCAGC
>ENST00005546.9
TTTATCGC
TTAGGGTAT

此处,f1 的内容用于构建数组 a 的键。读取第一个文件后,RS='>' 将更改第二个文件的记录分隔符。

in a 将检查第一行是否与数组 a

中的键匹配

编辑(通用解决方案): 如果必须在 Input_file 中查找多个字符串,请提及所有它们在 awk 变量 search 中,用 ,(逗号)分隔,应该打印所有匹配的(相应的行)。

awk -v search="ENST00001234.1,ENST00002235.4" '
BEGIN{
  num=split(search,arr,",")
  for(i=1;i<=num;i++){
    look[">"arr[i]]
  }
}
/^>/{
  if([=10=] in look){ found=1  }
  else          { found="" }
}
found
' Input_file

如果您想从另一个文件中读取 ID(需要在 Input_file 中搜索),请尝试以下操作。其中 look_file 是包含所有 id 需要搜索的文件, Input_file 是实际内容文件。

awk '
FNR==NR{
  look[">"[=11=]]
}
/^>/{
  if([=11=] in look){ found=1  }
  else          { found="" }
}
found
' look_file  Input_file


对于单个文本搜索: 请您尝试以下。使用 GNU awk 中显示的示例编写和测试。可以根据他们的要求给出需要在变量 search 中搜索的字符串。

awk -v search="ENST00001234.1" '
/^>/{
  if([=12=]==">"search){  found=1  }
  else             {  found="" }
}
found
' Input_file

说明:为以上添加详细说明。

awk -v search="ENST00001234.1" '     ##Starting awk program from here and setting and setting search variable value what we need to look.
/^>/{                                ##Checking condition if a line starts from > then do following.
  if([=13=]==">"search){  found=1  }     ##Checking condition if current line equals to > search(variable value) then set found to 1 here.
  else             {  found="" }     ##else set found to NULL here.
}
found                                ##Checking condition if found is SET then print that line.
' Input_file                         ##Mentioning Input_file name here.

无需重新发明轮子。有几种生物信息学工具可用于此任务(使用序列 ID 列表提取 fasta 序列)。例如,seqtk subseq:

Extract sequences with names in file name.lst, one sequence name per line:

seqtk subseq in.fq name.lst > out.fq

它也适用于 fasta 个文件。 使用 conda install seqtkconda create --name seqtk seqtk 安装 seqtk 包,它有其他有用的功能,而且速度非常快。

另请参见:

Retrieve FASTA sequences using sequence ids
Extract fasta sequences from a file using a list in another file
How To Extract A Sequence From A Big (6Gb) Multifasta File?