2013-01-10 79 views
3

如何使用awk解析基於來自另一個文件的數據的文件。使用awk解析

我犯了一個腳本:

BEGIN{ FS="\t" ; OFS="\t" 

while((getline<"headfpkm")>0) { 
     ++a 
     id[a]=$1 
     fpkm[a]=$2 
     print id[a],fpkm[a] 
     } 
lastid=id[a] 
print lastid 
close("headfpkm") 
} 

/$lastid/{ 
     print $2,$3,$5,$7,$8,$14,fpkm[a] 
     a-- 
     lastid=id[a] 
} 
END{ print "total lines=",FNR,"\n\nfile 1 index: ",a} 

當我運行它:

/$ awk -f testawk.awk file2 

其正常運行的BEGIN部分,但犯規給任何輸出。

NM_000014  5.04503 
NM_000015  0.586677 
NM_000016  1.138332278 
NM_000017  0.64386 
NM_000018  3.61746 
NM_000019  2.8793 
NM_000020  10.846 
NM_000021  0.685098 
NM_000022  46388.6 
NM_000026  0.257471 
NM_000026 
total lines= 10 

file 1 index: 10 

查找部分有什麼問題?

文件2看起來是這樣的:

34  ACADM NM_000016  9606 hsa-miR-3148 3  80  87  0.003 -0.016 -0.094 0.082 0.112 -0.160 97 
34  ACADM NM_000016  9606 hsa-miR-3163 1  623  629  0.001 -0.022 -0.020 0.065 0.125 -0.01 57 
35  ACADS NM_000017  9606 hsa-miR-3921 3  68  75  0.013 0.192 -0.097 0.031 -0.039 -0.147 82 
35  ACADS NM_000017  9606 hsa-miR-4303 2  67  73  0.012 0.150 -0.052 0.013 -0.039 -0.036 31 
35  ACADS NM_000017  9606 hsa-miR-4653-5p 3  68  75  0.003 0.192 -0.097 0.031 -0.039 -0.157 84 
37  ACADVL NM_000018  9606 hsa-miR-124  2  31  37  0.003 0.023 -0.057 0.012 -0.032 -0.171 76 
37  ACADVL NM_000018  9606 hsa-miR-1827 2  135  141  -0.007 -0.043 -0.058 0.039 -0.069 -0.258 91 
37  ACADVL NM_000018  9606 hsa-miR-2682 2  134  140  0.003 -0.014 -0.058 0.004 -0.047 -0.232 87 
37  ACADVL NM_000018  9606 hsa-miR-449c 2  134  140  -0.035 -0.014 -0.058 0.004 -0.047 -0.270 92 
37  ACADVL NM_000018  9606 hsa-miR-506  2  31  37  -0.016 0.023 -0.057 0.012 -0.032 -0.190 80 
+0

+1但是,你可以添加一些樣本輸入?在大多數情況下,應該[避免]使用getline()'(http://awk.info/?tip/getline)。如果沒有它,可能有更簡單更安全的方法來解決您的問題。 – Steve

+0

我需要從文件中讀取一列。在這個測試案例中,我只使用了前10行的數據。該文件是巨大的。或者有沒有一種方法使用sed打印文件,並將每個流作爲awk的輸入? – WYSIWYG

+0

我明白'headfpkm'(和你的'while循環)正在產生你所描述的輸出。但是,如果你可以包含'file2'的一些內容將會很有幫助。你使用的方法幾乎肯定不是這樣做的方式。 – Steve

回答

3

這將是一個有點猜的,因爲我不是100%肯定爲你想完成的任務。更好的方法來解決你的問題,將是做這樣的事情:

BEGIN { 
    FS=OFS="\t" 
} 

FNR==NR { 
    c++ 

    a[$1]=$2 
    next 
} 

$3 in a { 
    print $2,$3,$5,$7,$8,$14,a[$3] 
} 

END { 
    printf "total lines=%s\n\nfile 1 index: %s\n", FNR, c 
} 

運行,如:

awk -f script.awk headfpkm file2 

結果:

ACADM NM_000016 hsa-miR-3148  80 87 -0.160 1.138332278 
ACADM NM_000016 hsa-miR-3163  623 629 -0.01 1.138332278 
ACADS NM_000017 hsa-miR-3921  68 75 -0.147 0.64386 
ACADS NM_000017 hsa-miR-4303  67 73 -0.036 0.64386 
ACADS NM_000017 hsa-miR-4653-5p 68 75 -0.157 0.64386 
ACADVL NM_000018 hsa-miR-124  31 37 -0.171 3.61746 
ACADVL NM_000018 hsa-miR-1827  135 141 -0.258 3.61746 
ACADVL NM_000018 hsa-miR-2682  134 140 -0.232 3.61746 
ACADVL NM_000018 hsa-miR-449c  134 140 -0.270 3.61746 
ACADVL NM_000018 hsa-miR-506  31 37 -0.190 3.61746 
total lines=10 

file 1 index: 10 
+0

@bharat_iyengar:是的,你可以寫,例如; 'if($ 3〜/ pattern /){...}'。請參閱我上面所做的更新。這些是你正在尋找的結果嗎? – Steve

+1

是的,它的工作。非常感謝。 我想知道,如果文件1是巨大的,並且我不希望將它保存在數組中,那麼聲明'if x in y'是否與'/ $ x /' – WYSIWYG

+0

相同',那麼是否可以運行兩個流同時 ?例如, 'sed''file1 | awk -f腳本文件2' – WYSIWYG