regex - gawk 到 awk 中的区间表达式

标签 regex awk expression intervals

我希望这是一个简单的修复

我最初编写了一个利用 gawk 的干净且简单的脚本,我首先使用它是因为当我解决原始问题时我发现了这个问题。我现在需要将其调整为仅使用 awk。

示例文件.fasta:

>gene1

>gene235
ATGCTTAGATTTACAATTCAGAAATTCCTGGTCTATTAACCCTCCTTCACTTTTCACTTTTCCCTAACCCTTCAAAATTTTATATCCAATCTTCTCACCCTCTACAATAATACATTTATTATCCTCTTACTTCAAAATTTTT

>gene335
ATGCTCCTTCTTAATCTAAACCTTCAAAATTTTCCCCCTCACATTTATCCATTATCACCTTCATTTCGGAATCCTTAACTAAATACAATCATCAACCATCTTTTAACATAACTTCTTCAAAATTTTACCAACTTACTATTGCTTCAAAATTTTTCAT

>gene406
ATGTACCACACACCCCCATCTTCCATTTTCCCTTTATTCTCCTCACCTCTACAATCCCCTTAATTCCTCTTCAAAATTTTTGGAGCCCTTAACTTTCAATAACTTCAAAATTTTTCACCATACCAATAATATCCCTCTTCAAAATTTTCCACACTCACCAAC


gawk '/[ACTG]{21,}GG/{print a; print}{a=$0}' file.fasta >"species_precrispr".fasta

我所知道的 awk 的工作原理如下:

awk '/[ACTG]GG/{print a; print}{a=$0}' file.fasta >"species_precrispr".fasta

因此,罪魁祸首是 {21,} 的区间表达式

我想要它做的是搜索它匹配包含我的“GG”匹配左侧至少 21 个核苷酸的每一行。

有人可以帮忙吗?

编辑:

感谢大家的帮助: 有多种有效的解决方案。要回复一些评论,请提供初始输出和达到的预期效果的更基本示例...

在 awk 命令之前: cat 文件1.fasta

>gene1
ATGCCTTAACTTTCAATAACTGG 
>gene2
ATGGGTGCCTTAACTTTCAATAACTG
>gene3
ATGTCAAAATTTTTCATTTCAAT
>gene4
ATCCTTTTTTTTGGGTCAAAATTAAA
>gene5
ATGCCTTAACTTTCAATAACTTTTTAAAATTTTTGG

以下代码均产生相同的所需输出:

原始代码

gawk '/[ACTG]{21,}GG/{print a; print}{a=$0}' file1.fasta 

稍作修改,在原始 awk 版本 >3.x.x 中添加间隔函数

awk --re-interval'/[ACTG]{21,}GG/{print a; print}{a=$0}' file1.fasta

允许修改 val 和正确的输出,未经测试,但应该适用于较低版本的 awk

awk -v usr_count="21" '/gene/{id=$0;next} match($0,/.*GG/){val=substr($0,RSTART,RLENGTH-2);if(gsub(/[ACTG]/,"&",val)>= usr_count){print id ORS $0};id=""}' file1.fasta

awk --re-interval '/^>/ && seq { if (match(seq,"[ACTG]{21,}GG")) print ">" name ORS seq ORS} /^>/{name=$0; seq=""; next} {seq = seq $0 } END { if (match(seq,"[ACTG]{21,}GG")) print ">" name ORS seq ORS }' file1.fasta

期望的输出:仅获取匹配 GG 之前的基因名称和具有 21 个核苷酸的序列

>gene1
ATGCCTTAACTTTCAATAACTGG 
>gene5
ATGCCTTAACTTTCAATAACTTTTTAAAATTTTTGG

最后只是为了显示丢弃的行

>gene2
ATG-GG-TGCCTTAACTTTCAATAACTG # only 3 nt prior to any GG combo 
>gene3
ATGTCAAAATTTTTCATTTCAAT # No GG match found 
>gene4
ATCCTTTTTTTTGGGTCAAAATTAAA # only 14 nt prior to any GG combo 

希望这对其他人有帮助!

最佳答案

编辑:根据OP评论也需要打印基因ID,然后尝试以下操作。

awk '
/gene/{
  id=$0
  next
}
match($0,/.*GG/){
  val=substr($0,RSTART,RLENGTH-2)
  if(gsub(/[ACTG]/,"&",val)>=21){
    print id ORS $0
  }
  id=""
}
' Input_file

或者根据OP的要求使用上述解决方案的单行形式:

awk '/gene/{id=$0;next} match($0,/.*GG/){val=substr($0,RSTART,RLENGTH-2);if(gsub(/[ACTG]/,"&",val)>=21){print id ORS $0};id=""}' Input_file


您能否尝试仅使用所示示例进行以下编写和测试。

awk '
match($0,/.*GG/){
  val=substr($0,RSTART,RLENGTH-2)
  if(gsub(/[ACTG]/,"&",val)>=21){
    print
  }
}
' Input_file

或者更通用的方法,创建一个变量,用户可以在其中提到用户希望匹配的值应该出现在 GG 之前。

awk -v usr_count="21" '
match($0,/.*GG/){
  val=substr($0,RSTART,RLENGTH-2)
  if(gsub(/[ACTG]/,"&",val)>=usr_count){
    print
  }
}
'  Input_file

说明:为上述内容添加详细说明。

awk '                                ##Starting awk program from here.
match($0,/.*GG/){                    ##Using Match function to match everything till GG in current line.
  val=substr($0,RSTART,RLENGTH-2)    ##Storing sub-string of current line from RSTART till RLENGTH-2 into variable val here.
  if(gsub(/[ACTG]/,"&",val)>=21){    ##Checking condition if global substitution of ACTG(with same value) is greater or equal to 21 then do following.
    print                            ##Printing current line then.
  }
}
' Input_file                         ##Mentioning Input_file name here.

关于regex - gawk 到 awk 中的区间表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62001815/

相关文章:

linux - 在管道 awk 输出上打印循环输入文件名

regex - BASH:搜索字符串并准确显示子字符串在其中出现的确切次数

expression - Informatica 表达式将字符串转换为日期

c# - 将 Expression<Func<TModel,Boolean?>> 转换为 Expression<Func<TModel,Boolean>>

regex - 如何组合用正则表达式提取的句子中的所有单词?

javascript 测试函数总是返回 false

regex - 打印字段也包含 FS 字符?

javascript - JavaScript 中的正则表达式,如果使用后跟问号的分组,则始终为 ‘undefined’

java - 使用正则表达式提取字符串

java - Spring:如何在投影中使用SpEL表达式