2011-08-25 163 views
3

我有大量的數據,我從文本文件導入。這些文件被預格式化,這樣我可以導入每列作爲一個bash數組:是否可以將bash數組作爲變量傳遞給awk?

2GYS鏈=(AB)hresname =(BMA FUC NAG NDG)hresnumber =()hatom =()

現在我想從含有格式化這樣幾行文件提取信息:

ATOM 1N的THR A 4 30.127 13.123 1.297 1.00 39.96ñ

例如,我想提取所有第一列是ATOM的行,第五列匹配鏈式數組(在這種情況下,它將是A和B)。

UPDATE。這是我曾嘗試:

for c in "${chain[@]}" ; do 
    awk -v pdbid="$pdbid" -v c="$c" '{ if($1 == "ATOM" && $5==c) { print $0 } }' ${pdbid}.pdb >> ../../properpdb/${pdbid}_${c}.pdb 
done 

for c in "${chain[@]}" ; do 
for r in "${hresname[@]}" ; do 
    awk -v pdbid="$pdbid" -v c="$c" -v r="$r" '{ if($1 == "HETATM" && $5==c && $4==r) { print $0 } }' ${pdbid}.pdb >> ../../properpdb/${pdbid}_${c}.pdb 
done 
done 

的問題是,如預期這將產生與任一鏈A或B,但不能同時與文件中的文件。此外,它不會產生數組「鏈」和「hresname」的所有可能組合,它只會將「hresname」添加到只有一個「鏈」可用的文件。

+1

你的意思是在你的awk代碼'$ ==您C'? '$ 5 = c'將var'c'中的值賦給當前記錄的第5列。更一般地說,爲什麼不在awk中構建一些代碼來解析輸入文件,並且如果可能的話,更改輸入文件的格式以使其在awk中時不需要解析。祝你好運! – shellter

+0

感謝您發現了這個錯誤,Shawn Chin。改變輸入的格式不是一個大問題。至於你的第一個建議,由於兩個原因,它有點複雜:1)這個腳本屬於一個長bash管道; 2)我根本不知道任何awk。 – mirix

+0

鑑於上述輸入數據,您是否可以發佈期望的最終輸出以及管道的僞代碼。你是否真的認爲每條'記錄'都在一條線上(根據你的示例數據)?您展示的awk完全是一種習慣用法,但您可能會從使用關聯數組和printf語句中受益。 – shellter

回答

1

我的解決方案是在bash中構建awk腳本的一部分,特別是匹配函數。

您似乎希望將匹配$1 == "ATOM" && ($5==c[0] || $5==c[1]...) {print $0}的字段導出到該文件。

在bash,構建匹配功能:

cmatch="\$5==\"${chain[0]}\"" 
for element in $(seq 1 $((${#chain[@]} - 1))); do cmatch+=" || \$5==\"${chain[$element]}\""; done 
#cmatch should now be of the form "$5==A || $5==B" 

#do the same thing for rmatch 
rmatch="\$4==\"${hresname[0]}\"" 
for element in $(seq 1 $((${#hresname[@]} - 1))); do rmatch+=" || \$4==\"${hresname[$element]}\""; done 

現在可以調整你的AWK-腳本以包含所需的位:(行情繼續是一種痛苦,因爲你需要確保$ 1獲取awk unmleted,但$ cmatch被評估。)

rmatch='$1=="HETATM" && ('"$cmatch"') && ('"$rmatch"')' #order is important here :) 
cmatch='$1=="ATOM" && ('"$cmatch"')' 

所以現在你的匹配腳本應該是完整的。

awk "$cmatch" ${pdbid}.pdb >> ../../properpdb/${pdbid}_c.pdb 
awk "$rmatch" ${pdbid}.pdb >> ../../properpdb/${pdbid}_c.pdb 

我真的不明白輸出文件名,../../properpdb/${pdbid}_${c}.pdb,因爲這似乎表明對C的每一個元素,這是你不想要的東西單獨的文件?

如果你想用C的元素,這些劃分,那麼它的稍微簡單,構建rmatch陣列像上面,然後像做

for c in "${chain[@]}" ; do 
    awk -v c="$c" '$1=="ATOM" && $5==c' ${pdbid}.pdb >> ../../properpdb/${pdbid}_${c}.pdb 
    awk -v c="$c" '$1=="HETATM" && $5==c && ('"$rmatch"')' ${pdbid}.pdb >> ../../properpdb/${pdbid}_${c}.pdb 
done 

如果希望所有ATOM元素第一,還是......

for c in "${chain[@]}" ; do 
    awk -v c="$c" '$5==c && ($1=="ATOM" || ($1=="HETATM" && ('"$rmatch"')))' ${pdbid}.pdb >> ../../properpdb/${pdbid}_${c}.pdb 
done 

,如果你希望它們混合

相關問題