2016-05-16 55 views
0

我有一組帶有基因標識符的製表符分隔的文件,第一列中的每個後續列都表示具有第一列給定基因值的單個樣本。下面是我的文件之一,只有少數樣本的截斷示例:Awk添加可變數目的缺失值

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 statements,並AWK 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)。非常感激任何的幫助! 由於

+1

您的腳本是一個shell腳本,而不是一個'awk'腳本在一起的名字。 – chepner

+2

閱讀書籍克里斯約翰遜的Shell Scripting Recipes和Arnold Robbins編寫的Effective Awk Programming第4版。 –

+0

@GreysonB你說你的腳本是製表符分隔的。具有'PAX8'和'GUCA1A'的線也是所需數量的標籤,例如,在基因名稱後的三個標籤中的例子? –

回答

4

如果要假設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即使沒有新的字段被for循環添加,也會使用新的OFS爲每一行重寫$ 0。

如果最大數量的字段不一定出現在第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 
+0

不錯的觸摸朋友:) – sjsam

0

輸入

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-SID一個內膽爲上述

​​
0

這是我的看法:

腳本。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行中僅具有名稱的線輸出的模板。
  • 第二個動作照片無論是線上還是與模板