“Lista de argumentos muito longa” em loop

4

Meu script de shell é assim:

#!/bin/bash

for file in *.fasta
do

signalp $file > $file.txt

done

Na pasta de trabalho, tenho 18.000 arquivos .fasta. Eu quero correr cada um através do programa signalp. Eu acho que são muitos arquivos na pasta, mas não sei como ajustar meu código. Alguma ajuda?

    
por user2862862 13.07.2015 / 00:07

2 respostas

6

Você pode usar find :

find . -maxdepth 1 -type f -exec sh -c 'signalp "$1" >"$1".txt' _ {} \;
  • -maxdepth 1 fará find procurar por arquivos ( -type f ) apenas no diretório atual

  • sh -c 'signalp "$1" >"$1".txt' executará o comando signalp em todos os arquivos encontrados e salvará a saída nos arquivos nomeados após adicionar .txt aos nomes de arquivos originais.

por 13.07.2015 / 00:14
1

Você está recebendo um erro argument list too long porque não está citando seus argumentos. Há uma expansão ocorrendo - embora seja difícil dizer definitivamente o que é - sobre o valor de $file que gera mais argumentos . Minha teoria é que um dos seus nomes de arquivo contém outro * que novamente se expande para corresponder todos os seus arquivos correspondentes novamente.

Você pode fazer isso no shell - e você não precisa invocar um shell inteiro novo via find para fazer isso.

Basta fazer isso:

for f in ./*.fasta
do  signalp "$f" >"$f.txt"
done

... ver? As aspas duplas impedirão que o conteúdo da variável de shell iterável $f seja interpretado de qualquer maneira, mas literalmente - mesmo que $f contenha metacaracteres expansíveis do tipo.

No entanto, não é a melhor solução para grupos de arquivos de 18k. Ele funcionará , mas seria melhor se você pudesse agrupá-lo mais .

Como exemplo, vamos supor que haja algum tipo de ordem para os próprios nomes dos arquivos. Talvez eles tenham nomes como ...

aaa001.fasta
...
bbb001.fasta

E assim por diante. Nesse caso, você poderia fazer algo como:

for l in a b c d e f g h i j k l m n o p q r s t u v x y z
do    for  f in "./$l$l$l"*.fasta
      do   singalp "$f" >"$f.txt"
done; done

... e assim você não precisaria reter toda a lista de 18k na memória pela duração do loop.

    
por 13.07.2015 / 06:35