2011-08-25 162 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 

,如果你希望它们混合

相关问题