Como copiar linhas de múltiplos arquivos em um novo arquivo e manter o nome do arquivo?

1

Eu tenho 81 arquivos no formato .fasta que contêm (até) 53 itens. Tais como:

/User/MyData/Sample_1.fasta
/User/MyData/Sample_2.fasta
....
/User/MyData/Sample_81.fasta

Cada arquivo .fasta contém um ID de nome e uma string de caracteres delimitados como:

>AT1G00001
ATCCACTGCTGTGTACCTGATCAGTGCTGACCCAYTGTGACACTGTG
>AT2G00002
AAAAATTTTGCCCGTGTGGGCCAAACTGTCATGCATGCACCGTACGTGCATGCAT
....
>ATXGXXXXX(up to 53)
AAACCCTCTTTGTGCCTGTGCATGCA

Eu gostaria de copiar strings de cada um dos meus 81 arquivos .fasta para um novo arquivo .fasta, como:

/User/MyData/AT1G00001.fasta
/User/MyData/AT2G00002.fasta
....
/User/MyData/ATXGXXXXX.fasta

E o conteúdo de um deles contém (após a cópia de todos os arquivos 'Sample_X.fasta' no diretório):

>Sample_1
ATCCACTGCTGTGTACCTGATCAGTGCTGACCCAYTGTGACACTGTG
>Sample_2
ATCGACTCCCGTAGGACTGATTTTTCTGACCCCATTGTGACACTGTG
....
>Sample_81
TTCTGACCCCATTGTGACACTGTGATCGACTCCCGTAGGACTGATTT

Eu me deparei com uma ou duas perguntas semelhantes, mas nada exatamente com a nuance de preservar o SampleName no arquivo de saída copiado e estou tendo alguma dificuldade em obter exemplos de perguntas semelhantes, mas diferentes, para funcionar.

Muito obrigado por qualquer ajuda!

    
por MoGo 27.04.2015 / 07:39

3 respostas

1

Eu tenho o seguinte código para você; abaixo dela há uma explicação de como funciona.

Primeiro, vá para o diretório de trabalho ( cd /User/MyData/ ) para executar este programa:

awk '
  FNR==1 { sample = FILENAME ; sub(/\.fasta/, "", sample }
  /^>/   { target = substr($0,2)".fasta" ; next }
         { print ">" sample > target ; print > target }
' Sample_*.fasta

O programa awk itera sobre todos os arquivos Sample_*.fasta . No início de cada arquivo de entrada ( FNR==1 ), ele extrai o nome da amostra do nome do arquivo atual removendo o sufixo ".fasta". Se uma linha começar com > , o nome de arquivo de destino desse registro será retirado após o caractere > e o sufixo do nome de arquivo ".fasta" será anexado. Para o outro tipo de linhas, o nome da amostra extraído anteriormente é gravado no arquivo de destino e, em uma segunda linha, os dados atuais são gravados.

Nota: Se você observar problemas com "muitos descritores de arquivos abertos", a melhor opção é mudar para o GNU awk , se possível!

Se o GNU awk não for ou não puder ser disponibilizado na sua plataforma, você precisará de algumas alterações adicionais; a chave é fechar cada arquivo depois de gravar nele, usando a função close() , com a conseqüência de que você tenha que anexar aos arquivos fechados. (Isso é mais complexo e também menos produtivo, então vale a pena pensar em obter o GNU awk e usar a primeira variante.)

Essas alterações resultariam em um programa como:

# because of the append operation you need to empty the file targets
# before calling subsequent awk code, e.g. by: rm -f AT???????.fasta
awk '
  FNR==1 { sample = FILENAME ; sub(/\.fasta/, "", sample }
  /^>/   { target = substr($0,2)".fasta" ; next }
         { printf ">%s\n%s\n", sample, %0 >> target ; close(target) }
' Sample_*.fasta

Observe que, antes de chamar o programa awk , é necessário remover ou esvaziar quaisquer arquivos de saída existentes de chamadas anteriores (caso contrário, sua nova saída seria anexada aos dados existentes anteriormente nos respectivos arquivos de saída ).

    
por 27.04.2015 / 08:24
0

Embora seja interessante saber o que você tentou até agora, aqui está um exemplo de como awk poderia ser usado para este trabalho:

awk '
    FNR == 1 {
        sub(/\.fasta$/, "", FILENAME)
    }
    /^>/ && sub(/^>/, "") {
        newfile = $0 ".fasta"
        next
    }
    {
        print ">" FILENAME >> newfile
        print $0 >> newfile
    }' Sample_*.fasta
    
por 27.04.2015 / 08:24
0

Alguns shell: isso será muito mais lento que um programa awk.

cd /User/MyData
for sample in Sample*.fasta; do
    sample_name=${sample%.fasta}
    while read name; read data; do
        name=${name#>}
        printf ">%s\n%s\n" "$sample_name" "$data" >> "$name.fasta"
    done < "$sample"
done
    
por 27.04.2015 / 15:40