【问题标题】:print certains columns by header name with spaces on it (awk,sed)按标题名称打印某些列,上面有空格(awk,sed)
【发布时间】:2016-04-09 05:59:30
【问题描述】:

我想根据标题名称从文件中提取某些列。一些名称有空格(文件是制表符分隔的)。我无法删除或替换这些空间,因为下游应用程序会受到影响。我正在寻找的是根据标题名称提取一些列并按我想要的顺序输出它们

这是我的文件示例:

 Sample Note Intragenic Rate ABCDE_177447
 1032 NA 0.97867626 0.9300704670625763 0.72782564
 ABCDE_177447 NA 0.97836965 1.0 0.87218356 
 ABCDE_188399 NA 0.97859967 0.905527730405171 0.81188565
 ABCDE_189595 NA 0.9787659 0.9059075892313707 0.8089241
 ABCDE_189596 NA 0.9788054 0.9065243881070291 0.8092951

我想要的输出;

 Sample Intragenic ABCDE_177447
 1032 0.97867626 0.9300704670625763 0.72782564
 ABCDE_177447 0.97836965 0.87218356 
 ABCDE_188399 0.97859967 0.81188565
 ABCDE_189595 0.9787659 0.8089241
 ABCDE_189596 0.9788054 0.8092951

我已经尝试过这个解决方案AWK extract columns from file based on header selected from 2nd file

但它不适用于名称上的空格,对于此解决方案 Extracting columns from a file 也是如此

我也试过了

$cat cols.awk

BEGIN {
 n=split(cols,col)
 for (i=1; i<=n; i++) s[col[i]]=i
}
NR==1 {
 for (f=1; f<=NF; f++)
   if ($f in s) c[s[$f]]=f
 next
}
{ sep=""
 for (f=1; f<=n; f++) {
   printf("%c%s",sep,$c[f])
   sep=FS
 }
 print ""
}

但是当我像awk -F\t -f cols.awk.sh -v cols="Note,Sample,Intragenic Rate" metrics.txt 这样运行我的脚本时,我得到了以下错误:

awk: illegal field $(), name "1"
 input record number 2, file metrics.txt
 source line number 12

【问题讨论】:

    标签: bash awk sed


    【解决方案1】:

    你可以使用这个 awk:

    awk -v cols='Sample,Intragenic,ABCDE_177447' 'BEGIN{FS=OFS="\t"; nc=split(cols, a, ",")} NR==1{for (i=1; i<=NF; i++) hdr[$i]=i} {for (i=1; i<=nc; i++) if (a[i] in hdr) printf "%s%s", $hdr[a[i]], (i<nc?OFS:ORS)}' file
    
    Sample  Intragenic  ABCDE_177447
    1032    0.97867626  0.72782564
    ABCDE_177447    0.97836965  0.87218356
    ABCDE_188399    0.97859967  0.81188565
    ABCDE_189595    0.9787659   0.8089241
    ABCDE_189596    0.9788054   0.8092951
    

    使用cols 命令行参数,您可以传递以逗号分隔的列列表以进行打印。

    这里是更具可读性的 awk:

    awk -v cols='Sample,Intragenic,ABCDE_177447' 'BEGIN {
       FS=OFS="\t"
       nc=split(cols, a, ",")
    }
    NR==1 {
       for (i=1; i<=NF; i++)
          hdr[$i]=i
    }
    {
       for (i=1; i<=nc; i++)
          if (a[i] in hdr)
             printf "%s%s", $hdr[a[i]], (i<nc?OFS:ORS)
    }' file
    

    【讨论】:

    • 感谢@anubhava,你能告诉我如何包含像 yourfile.sh "cols1,cols 2" inputfile 这样的命令行参数吗?
    • yourfile.sh里面你可以保存这个awk命令:awk -v cols="$1" 'BEGIN{FS=OFS="\t"; nc=split(cols, a, ",")} NR==1{for (i=1; i&lt;=NF; i++) hdr[$i]=i} {for (i=1; i&lt;=nc; i++) if (a[i] in hdr) printf "%s%s", $hdr[a[i]], (i&lt;nc?OFS:ORS)}' "$2"然后作为chmod +x yourfile.sh; ./yourfile.sh "cols1,cols 2" inputfile运行它
    【解决方案2】:
    awk '{sub(/Note Intragenic Rate/,"Intragenic")}{sub(/NA/, "")}NR>2{sub($3, "")}1' file
    
    Sample Intragenic ABCDE_177447
    1032  0.97867626 0.9300704670625763 0.72782564
    ABCDE_177447  0.97836965  0.87218356 
    ABCDE_188399  0.97859967  0.81188565
    ABCDE_189595  0.9787659  0.8089241
    ABCDE_189596  0.9788054  0.8092951
    

    【讨论】:

      猜你喜欢
      • 2015-06-19
      • 1970-01-01
      • 2015-01-05
      • 2015-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-09
      • 2021-07-20
      相关资源
      最近更新 更多