Bash: Cat на основе переменной массива - PullRequest
1 голос
/ 01 сентября 2011

Я хочу объединить два или более файлов в зависимости от того, содержат ли имена элементы из массива или нет.

Я читаю этот тип файлов построчно (proteome.pisa):

2PJY_p  chain=(B C) hresname=() hresnumber=()   hatom=()    model=()    altconf=()
2Q7N_p  chain=(A E F G H I J K L)   hresname=(FUC MAN NAG)  hresnumber=()   hatom=()    model=()    altconf=()

Для каждой строки скрипт извлекает строку в первом столбце и определяет ее как переменную pdbid.Затем он берет второй столбец и определяет его как массив (цепочка элементов $ c).Затем он проверяет, существует ли файл с именем $ {pdbid} _ $ {c} _p.pdb, и, если это так, объединяет его содержимое в файл $ {pdbid} _p _ $ {цепочки} .pdb

Это сценарий:

while read line ; do

echo "$line" > pdb.line
cut -f1 pdb.line > pdb.list
sed -i 's/.*/\"&\"/' pdb.list
sed -i 's/_p//g' pdb.list
awk '{ printf "pdbid="; print }' pdb.list > pdbid.list

cut -f2 pdb.line > chain.list

source pdbid.list
source chain.list

chains=`printf "%s" "${chain[@]}"`

for c in ${chain[@]} ; do
if [ ${#chain[@]} -gt 1 ] && \
   [ -f ${pdbid}_${c}_p.pdb ] ; then  
cat ${pdbid}_${chain[$c]}_p.pdb >> ${pdbid}_p_${chains}.pdb
fi
done

done < proteome.pisa

Ожидаемое поведение должно было слить, например, для первой строки, 2PJY_p_B.pdb и 2PJY_p_C.pdb в файле с именем 2PJY_p_BC.pdb.Тем не менее, на самом деле он объединяет первый файл дважды.Я не могу понять, почему ...

Ответы [ 3 ]

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

Я бы предложил предварительно обработать ввод в более простую форму с sed, а затем повторить цикл.Предполагается, что chain=(...) всегда является первым таким атрибутом в строке.

#!/bin/sh

# Replace 2ICQ_p chain=(A B C ... Z) attribs= ...   with
# 2ICQ_p A B C ... Z
sed 's/ chain=\(//;s/\).*//' <proteome.pisa |
while read pdbid chain; do
    chains=${chain/ /}
    for c in $chain; do
        test -e ${pdbid}_${c}_p.pdb || continue
        cat ${pdbdid}_${c}_p.pdb
    done >${pdbid}_p_${chains}.pdb
done

Это позволяет избежать использования временных файлов, которые пронизывают ваш первый скрипт;поиск сгенерированного файла также выглядит довольно поразительно, если не тревожно (обычно вы можете использовать обратные пометки для такого рода вещей, но они здесь на самом деле не требуются).некоторые (например, Linux) хотят, чтобы буквальные скобки были разделены обратной косой чертой, другие (например, Mac OSX) этого не делают.Если это не сработает, попробуйте удалить обратную косую черту.

read с несколькими именами переменных разделяет входные данные на пробельные символы, так что имя первой переменной получает первый токен и т. Д .;последняя именованная переменная получает все, что осталось, без дополнительного разделения пробелов.continue переходит к следующей итерации окружающего цикла for или while.Помимо этого, это должно быть довольно очевидно.Если вы действительно хотите сделать все это в чистой оболочке Bourne, замену sed в начале, вероятно, можно заменить чем-то, включающим подстановку строк.

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

Это отличный вопрос, поскольку он демонстрирует, что bash не может делать все самостоятельно. Вместо этого ему нужны помощники, такие как awk, cut, ... Я просмотрел ваше решение, и кажется, что после двух строк source вы ожидаете, что у вас будут установлены переменные pdbid, chain и chain. Тем не менее, ваш сценарий не установил их правильно, и я могу помочь с этой частью. Я не очень хорошо знаю Perl, но думаю, что в этом случае Perl будет хорошо работать. Вот makevars.pl :

while (<STDIN>) {
    my($line) = $_;
    if ($line =~ /^(.*)_p.*chain=\((.*)\).*hresname.*$/) {
        print "pdbid=$1\n";
        print "chain=($2)\n";
        $chains = $2;
        $chains =~ s/ //g;
        print "chains=$chains\n";
    }
}

А вот и скрипт оболочки:

while read line
do

    echo "$line" | perl makevars.pl >setvars.sh
    source setvars.sh
    # Now, pdbid, chain, and chains are set, do your things

done < proteome.pisa

Надеюсь, это поможет.

0 голосов
/ 02 сентября 2011

Похоже, проблема заключается в определении массива в этой строке:

cat ${pdbid}_${chain[$c]}_p.pdb >> ${pdbid}_p_${chains}.pdb

Изменение на:

cat ${pdbid}_${c}_p.pdb >> ${pdbid}_p_${chains}.pdb

кажется, чтобы решить проблему.

Кроме того, я дважды цитировал все вхождения "$ {chain [@]}".

...