добавить имя файла в заголовки fasta в цикле с помощью awk?

#bash #loops #awk #header #fasta

#bash #циклы #awk #заголовок #fasta

Вопрос:

Я знаю, что об этом спрашивали раньше, но я не могу найти работающее решение — по какой-то причине, когда я пробую любое из других решений, опубликованных в stackoverflow, они просто НЕ будут работать

У меня есть каталог, содержащий более 900 файлов fasta, все они заканчиваются на «.faa», некоторые из имен:

TLLD001.faa TLLD002.faa TLLD003.faa TLLD004.faa TLLD005.faa

и т.д. и т.п.

в каждом файле заголовки fasta:

    >scaffold4567
   WRVLSTSFNGIKYEQSAAFAMIPSTT
   >scaffold0034
   EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ
  

или

    >NODE_212
   WRVLSTSFNGIKYEQSAAFAMIPSTT
   >NODE_86667
   EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ
  

и т.д. и т.п.

Я хочу просмотреть все файлы и заменить заголовок, добавив имя файла, например, TLLD001.faa

    >scaffold4567
   WRVLSTSFNGIKYEQSAAFAMIPSTT
   >scaffold0034
   EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ
   >scaffold7667
   WRVLSTSFNGIKYEQSAAFAMIPSTT
   >scaffold6778
   EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ
  

должно стать

    >TLLD001_scaffold4567
   WRVLSTSFNGIKYEQSAAFAMIPSTT
   >TLLD001_scaffold0034
   EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ
   >TLLD001_scaffold7667
   WRVLSTSFNGIKYEQSAAFAMIPSTT
   >TLLD001_scaffold6778
   EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ
  

это работает хорошо, но я должен каждый раз указывать один файл
$awk '/>/{sub(">","amp;"FILENAME"_");sub(/.faa/,x)}1' TLLD001.faa

так что не моя чашка чая

похоже, это сработало в 3-4 файлах, которые я сделал в качестве теста, но это не будет работать в моем каталоге файлов 900 — занимает вечность-

 for i in *.faa; do 
    sed -i "s/^>/>${i}_/g" *.faa
done
  

и следующее вообще не работает:

 $for file in *.fasta; do awk '/^>/ {printf("n%sn",$0);next; } { printf("%s",$0);}  END {printf("n");}' < $file > "`basename $file .fasta`_single-line.fasta"; done
  

и

 $for file in *.faa; do awk '/>/{sub(">","amp;"${file}"_");sub(/.faa/,x)}1' < $file > "`basename $file .faa`_mod.faa"; done
  

и я не знаю почему! любая помощь и объяснение того, как использовать этот всемогущий, но загадочный «awk», будут высоко оценены

спасибо P

Комментарии:

1. Не могли бы вы, пожалуйста, указать свои образцы / коды в ТЕГАХ КОДА, похоже, вы использовали теги кавычек, что затрудняет понимание образцов.

Ответ №1:

это должно сделать

 $ for f in *.faa; do sed -i "s/^>/>${f}_/" "$f"; done
  

однако также будет вставлено расширение файла. Чтобы удалить расширение, измените на ${f%.*}

Ответ №2:

Решение sed — это правильный путь, но вы повторили глобус в команде!

Вместо

 for f in *.faa; do sed -i "s/^>/>${f%.faa}/g" *.faa; done
  

Используйте переменную ${f} в команде sed, иначе она снова расширяется для команды sed!

 for f in *.faa; do sed -i "s/^>/>${f%.faa}/g" "${f}"; done
  

Я также сделал нам некоторую замену переменной bash, чтобы просто удалить.faa из файла.

Комментарии:

1. вам все равно нужно заключить в кавычки "${f}" или просто "$f" .

Ответ №3:

Попробуйте однострочный Perl.

 perl -i -0777 -pe ' $x=$ARGV;$x=~s/.faa//g; s/>/>${x}_/ ' *faa
  

Вот распад

 $ cat  TLLD001.faa
>scaffold4567
WRVLSTSFNGIKYEQSAAFAMIPSTT
>scaffold0034
EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ
>scaffold7667
WRVLSTSFNGIKYEQSAAFAMIPSTT
>scaffold6778
EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ

$ cat TLLD002.faa
>NODE_212
WRVLSTSFNGIKYEQSAAFAMIPSTT
>NODE_86667
EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ
  

Выполнение команды без замены

 $ perl -0777 -pe ' $x=$ARGV;$x=~s/.faa//g; s/>/>${x}_/ ' *faa
>TLLD001_scaffold4567
WRVLSTSFNGIKYEQSAAFAMIPSTT
>scaffold0034
EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ
>scaffold7667
WRVLSTSFNGIKYEQSAAFAMIPSTT
>scaffold6778
EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ
>TLLD002_NODE_212
WRVLSTSFNGIKYEQSAAFAMIPSTT
>NODE_86667
EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ
  

С помощью in-replace

 $ perl -i -0777 -pe ' $x=$ARGV;$x=~s/.faa//g; s/>/>${x}_/ ' *faa
  

Файлы были изменены

 $ cat TLLD001.faa
>TLLD001_scaffold4567
WRVLSTSFNGIKYEQSAAFAMIPSTT
>scaffold0034
EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ
>scaffold7667
WRVLSTSFNGIKYEQSAAFAMIPSTT
>scaffold6778
EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ
$ cat TLLD002.faa
>TLLD002_NODE_212
WRVLSTSFNGIKYEQSAAFAMIPSTT
>NODE_86667
EQSAAFAMIPSTTSISWRVLSTSFNGIKYEQ
$
  

Ответ №4:

Я знаю, что он старый, но в версиях OSX sed -i опция ожидает расширения. Итак, вам нужно добавить -e аргумент и указать '' в качестве аргумента -i .

 for f in *.faa; do sed -i '' -e "s/^>/>${f%.faa}_/g" "${f}"; done
  

Для людей из OSX 🙂