【问题标题】:Awk adding variable number of missing valuesawk 添加可变数量的缺失值
【发布时间】:2016-05-16 16:59:08
【问题描述】:

我有一组制表符分隔的文件,第一列中包含基因标识符,随后的每一列代表一个单独的样本,第一列中包含该给定基因的值。这是我的一个文件的截断示例,其中只有几个示例:

DDR1 8.55578403700418 8.65526857898327 8.71701700266541 
MIR4640 8.55578403700418 8.65526857898327 8.71701700266541 
RFC2  5.47524925570941 5.88644077981836 5.77277342309348
HSPA6 4.12035662689116 4.01089068869244 3.82366440713502
PAX8  
GUCA1A   

我从Awk adding constant valuesBash Script Awk if statementsAWK if length statement append 那里得到了一些想法,由于我有几千行和可能数百列,具体取决于输入文件,我尝试这样编写脚本:

cd ../path/to/file

inputFile=inputFile.in
outputFile=outputFile.out

columnCount= $(awk -F"\t" 'NR==1 {print NF}' $inputFile)

awk '{ for (i = 1; i <= $columnCount; i++)

    if (i<$columnCount) {print $0"\t?"}' $inputFile > $outputFile
}'

但我不断收到语法错误。

$ awk -f missingValueAdder.awk 
awk: missingValueAdder.awk:3: cd ../path/to/file
awk: missingValueAdder.awk:3:    ^ syntax error
awk: missingValueAdder.awk:5: inputFile=inputFile.in
awk: missingValueAdder.awk:5:                    ^ syntax error
awk: missingValueAdder.awk:6: outputFile=outputFile.out
awk: missingValueAdder.awk:6                       ^ syntax error
awk: missingValueAdder.awk:8: columnCount= $(awk -F"\t" 'NR==1 {print NF}' $inputFile) 
awk: missingValueAdder.awk:8:                           ^ invalid char ''' in expression

所以我尝试了这个单线

 awk 'for (i=1;i<=NF;i++) BEGIN{FS=OFS="\t"} I<NF{print$0"\t?"}' inputFile.in > outputFile.out

但是从我的 for 循环开始出现另一个语法错误。无论如何,我的输出文件应该看起来像

DDR1 8.55578403700418 8.65526857898327 8.71701700266541 
MIR4640 8.55578403700418 8.65526857898327 8.71701700266541 
RFC2  5.47524925570941 5.88644077981836 5.77277342309348
HSPA6 4.12035662689116 4.01089068869244 3.82366440713502
PAX8    ?   ?   ? 
GUCA1A  ?   ?   ?

我想打印尽可能多的“?”由 NF 规定(在本例中为 3,但可能多达 100)。非常感激任何的帮助! 谢谢

【问题讨论】:

  • 您的脚本是一个 shell 脚本,而不是 awk 脚本。
  • 阅读 Chris Johnson 的《Shell Scripting Recipes》和 Arnold Robbins 的《Effective Awk Programming, 4th Edition》。
  • @GreysonB 你说你的脚本是制表符分隔的。有PAX8GUCA1A 的行还有所需的选项卡数,例如在示例中基因名称后的三个选项卡?
  • @LarsFischer 好问题。 PAX8 等行在第一列之后没有额外的制表符。

标签: bash if-statement for-loop awk


【解决方案1】:

如果您想假设文件中的最大字段数出现在第 1 行,请执行以下操作:

$ awk -v OFS="\t" 'NR==1 {cols=NF} {$1=$1; for (i=NF+1; i <= cols; i++) $i = "?"} 1' file
DDR1    8.55578403700418    8.65526857898327    8.71701700266541
MIR4640 8.55578403700418    8.65526857898327    8.71701700266541
RFC2    5.47524925570941    5.88644077981836    5.77277342309348
HSPA6   4.12035662689116    4.01089068869244    3.82366440713502
PAX8    ?   ?   ?
GUCA1A  ?   ?   ?

奇怪的$1=$1 位强制 awk 为每一行使用新的 OFS 重写 $0,即使 for 循环没有添加新字段。

如果最大字段数不一定出现在第 1 行,那么您可以对文件进行两次处理:一次找到最大数量;一次添加字段占位符:

awk -v OFS="\t" '
    NR == 1 {cols = NF}
    NR == FNR {if (NF>cols) cols=NF; next} 
    {$1=$1; for (i=NF+1; i <= cols; i++) $i = "?"} 
    1
' file file

【讨论】:

  • 好朋友 :)
【解决方案2】:

这是我的看法:

script.awk

NR==1 { for(i=2;i<=NF;i++) tmp=tmp "\t?" }
{ if (NF==1) print $1, tmp
  else print }

像这样使用它:awk -f script.awk yourfile

  • 第一行根据第 1 行中的字段计数确定仅具有名称的行中的输出模板。
  • 第二个操作将行或名称与模板一起打印

【讨论】:

    【解决方案3】:

    输入

    DDR1 8.55578403700418 8.65526857898327 8.71701700266541
    MIR4640 8.55578403700418 8.65526857898327 8.71701700266541
    RFC2  5.47524925570941 5.88644077981836 5.77277342309348
    HSPA6 4.12035662689116 4.01089068869244 3.82366440713502
    PAX8
    GUCA1A
    

    AWK 脚本

    awk '{
           if($0!=$1){
             printf "%s\n",$0
            }
            else{
            printf "%s\t?\t?\t?\t\n",$1
            }
         }' yourfilename > temp && mv temp yourfilename
    

    输出

    DDR1 8.55578403700418 8.65526857898327 8.71701700266541 
    MIR4640 8.55578403700418 8.65526857898327 8.71701700266541 
    RFC2  5.47524925570941 5.88644077981836 5.77277342309348
    HSPA6 4.12035662689116 4.01089068869244 3.82366440713502
    PAX8    ?   ?   ?   
    GUCA1A  ?   ?   ?
    

    GNU-Sed 用于上述的一个衬里

    sed -i 's/^\([[:alnum:]]*\)$/\1\t?\t?\t?/' yourfilename
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-21
      相关资源
      最近更新 更多