Eu tenho uma pasta com muitos arquivos (xyz1, xyz2, até xyz5025) e preciso executar um script em cada um deles, obtendo xyz1.faa, xyz2.faa e assim por diante.
O comando para um único arquivo é:
./transeq xyz1 xyz1.faa -table 11
Existe uma maneira de fazer isso automaticamente? Talvez uma combinação de tarefas a fazer?
for file in xyz*; do ./transeq "$file" "${file}.faa" -table 11; done
. Eu digito esse tipo de coisa o tempo todo. E se você deseja verificar se os nomes dos arquivos etc. estão sendo expandidos da maneira que deseja, basta colocar umecho
logo apósdo
a primeira vez e, em seguida, voltar ao histórico do shell e excluí-lo na segunda vez."$file".faa
é um pouco mais fácil de digitar como parte de uma linha interativa e seguro, porque.faa
não contém nenhum metacaractere de shell que precisa ser citado.xyz*
glob também coletará arquivos .faa. Para o bash, executeshopt -s extglob
( referência ) e usefor file in xyz!(*.faa) ...
para excluir os arquivos .faa do envio pelo loop.Se você instalar o GNU Parallel, poderá fazê-lo em paralelo da seguinte maneira:
Se você programar com muita CPU, deve acelerar um pouco.
fonte
Você pode fazer algo assim em uma
bash
linha de comando:Estamos gerando os números inteiros de 1 a 5025, um / linha, e os alimentando um a um para xargs, que encapsula o número inteiro
{}
e o transplanta na linha de comando ./transeq de maneira apropriada.Se você não tiver o recurso de expansão de chaves
{n..m}
, poderá chamar oseq
utilitário para gerar esses números.Ou você sempre pode emular a geração numérica via:
fonte
for i in {1..5025}; do ./transeq "xyz$i" "xyz$i".faa -table 11; done
é muito mais fácil pensar e digitar. Se você deseja imprimir comandos antes de executá-los, useset -x
.for i in
{1..5025}
para obter exatamente o mesmo resultado que o seu. Você também pode escreverfor ((i=1 ; i<=5025 ; i++)); do ./transeq "xyz$i" "xyz$i".faa -table 11; done
no bash, mas eu geralmente uso a{a..b}
sintaxe de intervalo, porque é mais rápido digitar.Usando find, útil quando seus arquivos estão espalhados dentro de diretórios
fonte
Supondo que você tenha mais de um núcleo e que cada chamada possa ser executada independentemente do restante, você ganhará bastante aceleração com execuções paralelas.
Uma maneira relativamente simples de fazer isso é através do
-P
parâmetroxargs
- por exemplo, se você tiver 4 núcleos:O comando
-n 1
dizxargs
para escolher apenas um argumento da lista para cada invocação (por padrão, ele passaria bastante) e o comando-P 4
para gerar 4 processos ao mesmo tempo - quando um morre, um novo é gerado.IMHO, você não precisa instalar o GNU paralelo para este caso simples -
xargs
basta.fonte
Você pode usar
xarg
ls | xargs -L 1 -d '\n' your-desired-command
-L 1
faz passar 1 item de cada vez-d '\n'
make output ofls
é dividido com base na nova linha.fonte