awk提取并打印第一次出现的模式

时间:2017-10-02 11:42:55

标签: awk

我正在尝试使用awk来提取并打印NM_的第一次出现以及NP_p.开头的部分。打印:而不是“|”为每个人。输入文件为tab-delimeted,但输出不需要。下面会执行,但打印文件中的所有行而不仅仅是模式。在我的5000多行的实际数据中可能有多个NMNP,但是只提取和打印每个行的第一次出现。我对RSTARTRLENGHTH概念仍然有点不清楚,但是使用第1行作为输入中的示例:

NM变量为NM_020469.2

NP变量为:p.Gly268Arg

我也包括了评论。谢谢你:)。

输入

Input Variant   HGVS description(s) Errors and warnings
rs41302905  NC_000009.11:g.136131316C>T|NM_020469.2:c.802G>A|NP_065202.2:p.Gly268Arg
rs8176745   NC_000009.11:g.136131347G>A|NM_020469.2:c.771C>T|NP_065202.2:p.Pro257=

期望的输出

rs41302905 NM_020469.2:c.802G>A:p.Gly268Arg
rs8176745 NM_020469.2:c.771C>T:p.Pro257=

AWK

awk -F'[\t|]' 'NR>1{ # define FS as tab and `|` to split each, and skip header line
              r=$1; nm=np="";  # create variable r with $1 and 2 variables (one for nm and the other for np, setting them to null)
              for(i=2;i<=NF;i++) { # start a loop from line2 and itterate
                  if ($i~/^NM_/) nm=$i;  # extract first NM_ in line and read into i
                  else if ($i~/^NP_/) np=substr($i,index($i,":")); # extract NP_ and print portion after : (including :)
                  if (nm && np) { print r,nm np; break }  # print desired output
              }
          }' input

5 个答案:

答案 0 :(得分:1)

Awk 解决方案:

awk -F'[\t|]' 'NR>1{
                  r=$1; nm=np="";
                  for(i=2;i<=NF;i++) {
                      if ($i~/^NM_/) nm=$i;
                      else if ($i~/^NP_/) np=substr($i,index($i,":"));
                      if (nm && np) { print r,nm np; break } 
                  }
              }' input
  • 'NR>1 - 从第二条记录开始处理

  • r=$1; nm=np="" - 初始化所需变量

  • for(i=2;i<=NF;i++) - 遍历字段(从第2个开始)

  • if ($i~/^NM_/) nm=$i - 将NM_...项目捕获为变量nm

  • else if ($i~/^NP_/) np=substr($i,index($i,":")) - 将NP_...项目捕获到变量np(从:开始直到结束)

  • if (nm && np) { print r,nm np; break } - 如果两个项目都已被捕获 - 打印并打破循环以避免进一步处理

输出:

rs41302905 NM_020469.2:c.802G>A:p.Gly268Arg
rs8176745 NM_020469.2:c.771C>T:p.Pro257=

答案 1 :(得分:1)

请您试着跟随并告诉我这是否有帮助。

awk '{
match($0,/NM_[^|]*/);
nm=substr($0,RSTART,RLENGTH);
match($0,/NP_([^|]|[^$])*/);
np=substr($0,RSTART,RLENGTH);
split(np, a,":");
  if(nm && np){
    print $1,nm ":" a[2]
}
}
'   Input_file

输出如下。

rs41302905 NM_020469.2:c.802G>A:p.Gly268Arg
rs8176745 NM_020469.2:c.771C>T:p.Pro257=

PS:由于您的示例Input_file中没有TAB,因此您可以在awk之后添加“\ t”,以防您的Input_file被TAB分隔,并且您希望将输出作为TAB分隔在Input_file之前添加OFS =“\ t”。

答案 2 :(得分:1)

简短的GNU awk 解决方案(带match功能):

awk 'match($0,/(NM_[^|]+).*NP_[^:]+([^[:space:]|]+)/,a){ print $1,a[1] a[2] }' input

输出:

rs41302905 NM_020469.2:c.802G>A:p.Gly268Arg
rs8176745 NM_020469.2:c.771C>T:p.Pro257=

答案 3 :(得分:1)

根据您发布的样本输入,这就是生成所需输出所需的全部内容:

$ awk -F'[\t|]+' 'NR>1{sub(/[^:]+/,"",$4); print $1, $3 $4}' file
rs41302905 NM_020469.2:c.802G>A:p.Gly268Arg
rs8176745 NM_020469.2:c.771C>T:p.Pro257=

如果您不是全部,那么请提供更具真实代表性的输入/输出。

答案 4 :(得分:1)

另一个替代awk提案。

awk 'NR>1{sub(/\|/," ")sub(/\|NP_065202.2/,"");print $1,$3,$4}' file

rs41302905 NM_020469.2:c.802G>A:p.Gly268Arg
rs8176745 NM_020469.2:c.771C>T:p.Pro257=