Usando um laço bash para executar um programa que usa aspas simples na linha de comando, onde aspas simples anulam a intenção do script bash

0

O problema:

Eu quero ser capaz de executar um programa dentro de um loop bash sobre cada arquivo .fna em um diretório, mas também quero que o nome do arquivo de saída tenha o mesmo nome de arquivo (sem a extensão), o problema é que o programa usa aspas simples para especificar seu arquivo de saída. Então, quando eu corro meu script, ele apenas imprime um arquivo chamado:

outputfile

O código:

 for fna in $(find . -name "*.fna")
do
    outputname = ${fna%.fna}
    outputfile = $outputname.rrna
    barrnap $fna --outseq 'outputfile'
done

Exemplo de entrada

Um arquivo chamado:

GCF_000003135.1_ASM313v1_genomic.fna

Com um exemplo do conteúdo:

>NZ_GG666849.1 Bifidobacterium longum subsp. longum ATCC 55813 SCAFFOLD1, whole genome shotgun 
sequence
AACCCCGTGGAGTTCACACAACAAGGTGTATTTAGTCAAGTCGGTGTTTCGTGTTTCGTCACTGATTTTTTTCACTGCGG
AAA

Saída desejada:

Um arquivo de saída do programa chamado:

GCF_000003135.1_ASM313v1_genomic.rrna
Peço desculpas pela bagunça disso, estou tendo problemas para pensar na melhor maneira de explicar o problema, se alguém puder sugerir uma melhoria no título, eu irei mudá-lo instantaneamente.

    
por Biomage 04.09.2018 / 11:20

1 resposta

1

O programa não usa aspas simples. As aspas simples são usadas para evitar que o shell execute expansões variáveis na string citada. As aspas serão removidas pelo shell antes de chamar o programa.

Nesse caso, as aspas simples não fazem nada, pois a string que eles citam é apenas uma string simples sem expansões para o shell executar (isso é um erro em seu código, você provavelmente queria $outputfile com aspas duplas) .

Se seus arquivos estiverem no diretório atual (e somente lá), você poderia fazer

for fasta in ./*.fna; do
    barrnap --outseq "${fasta%.fna}.rrna" "$fasta"
done

ou, com uma variável intermediária,

for fasta in ./*.fna; do
    outfile="${fasta%.fna}.rrna"
    barrnap --outseq "$outfile" "$fasta"
done

Aqui, usamos aspas duplas em vez de aspas simples, porque queremos que o shell realize a expansão dentro delas. Também movi o nome do arquivo de entrada para o final da linha de comando na invocação de barrnap de acordo com o manual .

Se seus arquivos estiverem localizados em qualquer número de subdiretórios no diretório atual, e você precisar usar find , não faça um loop pela saída de find , mas deixe find chamar seu programa:

find . -type f -name '*.fna' -exec sh -c '
    for fasta do
        barrnap --outseq "${fasta%.fna}.rrna" "$fasta"
    done' sh {} +

Aqui, find age como um gerador de nomes de caminho para o loop de shell.

Relacionados:

Seu código também tem alguns erros de sintaxe, pois as atribuições devem ser feitas sem espaços em torno de = . Expansões variáveis devem, além disso, ser duplamente citadas.

    
por 04.09.2018 / 11:27