Можно ли передать массив bash как переменную в awk? - PullRequest
3 голосов
/ 25 августа 2011

У меня есть большое количество данных, которые я импортирую из текстовых файлов.Файлы предварительно отформатированы, так что я могу импортировать каждый столбец как массив bash:

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

Теперь я хотел бы извлечь информацию из файлов, содержащих несколько строк, отформатированных следующим образом:

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

Например, я хотел бы извлечь все строки, в которых первый столбец является ATOM, а пятый столбец соответствует цепочечному массиву (в этом случае это будут и A, и B).

ОБНОВЛЕНИЕ.Вот что я пробовал:

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, но не файлы с обоими.Кроме того, он не создает все возможные комбинации массивов "chain" и "hresname", он просто добавляет "hresname" к файлам, для которых была доступна только одна "цепочка".

1 Ответ

1 голос
/ 21 сентября 2011

Мое решение состоит в том, чтобы собрать часть вашего скрипта awk в bash, в частности функцию соответствия.

Похоже, вы хотите, чтобы поля, соответствующие $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 без изменений, но $ 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

если вы хотите, чтобы они смешались

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...