Конвертация из тсв в фасту

У меня есть куча файлов TSV в моей папке, и для каждого из них я хотел бы получить файл фаста, где заголовок после знака ">" - это имя файла. Мой файл TSV имеет 5 столбцов без заголовка:

Таким образом:

входной файл называется: "A.coseq.table_headless.tsv" HIV1B-pol-seed 15 MAX 1959 GTAACAGACTCACAATATGCATTAGGAATCATTCAAGC выходной файл называется "A.fasta"

> a_max

GTAACAGACTCACAATATGCATTAGGAATCATTCAAGC

Я хочу запустить скрипт одновременно в bash для всех файлов, и у меня есть этот скрипт, который не работает, потому что в выражении awk print у меня есть фигурная скобка:

for sample in `ls *coseq.table_headless.tsv`
do
base1=$(basename $sample "coseq.table_headless.tsv")
awk '{print ">"${base1}"_"$3"\n"$5}' ${base1}coseq.table_headless.tsv > ${base1}fasta

done

Есть идеи, как исправить этот код? большое спасибо

3 ответа

Если базовое имя является частью до первого ".", вы также можете избавиться от цикла.

 awk '{split(FILENAME,base,"."); 
       print ">" base[1] "_" $3 "\n" $5 > base[1]".fasta"}' *coseq.table_headless.tsv

Другое решение awk:

awk '{ pfx=substr(FILENAME,1,index(FILENAME,".")-1); 
       printf(">%s_%s\n%s\n",pfx,$3,$5) > pfx".fasta" }' *coseq.table_headless.tsv 

  • pfx содержит первую часть имени файла (до 1-го .)

Другие опубликованные решения имеют несколько проблем:

  1. не закрытие файлов при их написании приведет к ошибкам "слишком много открытых файлов", если вы не используете GNU awk,

  2. вычисление имени выходного файла каждый раз, когда строка читается, а не один раз при открытии входного файла, неэффективно, и

  3. использование выражения в скобках в правой части перенаправления вывода - неопределенное поведение, поэтому будет работать только в некоторых awk (включая GNU awk).

Это будет работать надежно и эффективно во всех ауках:

awk '
    FNR==1 { close(out); f=FILENAME; sub(/\..*/,"",f); pfx=">"f"_"; out=f".fasta" }
    { print pfx $3 ORS $5 > out }
' *coseq.table_headless.tsv
Другие вопросы по тегам