Alterando sequencialmente o diretório e executando um script

3

Para minha vida, não consigo encontrar nenhuma ajuda sobre isso. Eu tenho, digamos, 2000 diretórios que eu preciso para executar um programa específico dentro Devido a limitações do programa, ele não pode simplesmente escrever 'Output1', 'Output2', 'Output3', etc. Ele tem que escrever 'Output' como sua saída arquivo e sobrescreverá qualquer outro arquivo chamado 'Saída', daí a necessidade de um diretório para cada instância única do programa. O que eu preciso é algo para esse efeito

Com s sendo o prefixo para o diretório. I. E., s0001, s0002 .... s2000 são os nomes dos diretórios.

cd s(n)
ls
cd s(n+1)

e com este comando de looping interrompido após

cd s2000

Eu estava tentando fazer isso funcionar por um

if 'cd s(n+1)' = 'cd s(2001)' then echo DONE

string, mas sem sucesso.

Qualquer ajuda é apreciada.

    
por MadisonCooper 08.06.2015 / 15:25

4 respostas

4

Os detalhes dependem da sua configuração. Se o diretório pai contiver somente os diretórios filhos s0001 a s2000, tudo que você precisa é fazer uma iteração sobre eles e iniciar o programa em cada um deles:

for d in s*; do
  cd "$dir" && run_program; cd ../;
done

Isso se moverá para cada diretório e lançará run_program . Uma vez terminado, ele recua.

Se você precisar especificar um intervalo de dirs, use isso:

for dir in s{0001..2000}; do
    cd "$dir" && run_program; cd ../
done

Por fim, se você quiser iniciar todos os processos simultaneamente (não que isso possa deixar seu computador de joelhos), use & :

for dir in s{0001..2000}; do
    cd "$dir" && run_program & cd ../
done

As versões mais antigas do bash não expandem {001..002} como 001 002 , mas como 1 2 . Se o seu bash não suporta isso, use esta abordagem:

seq 1 2000 | while read i; do 
   dir=$(printf '%0.4d\n' "$i")
   cd s"$dir" && run_program; cd ../;
done

O truque é gerar os números entre 1 e 2000 usando seq e, em seguida, usar printf para adicionar 0s iniciais conforme necessário.

    
por terdon 08.06.2015 / 16:20
2

Aqui está um script bash. Sinta-se à vontade para adaptá-lo às suas necessidades.

#!/bin/bash
#set -x
BASEDIR=/home/xieerqi

find "$BASEDIR" -type d -name "s[[:digit:]][[:digit:]][[:digit:]][[:digit:]]" -print0 | while IFS= read -r -d '' folder; do
        echo "$folder"
        cd "$folder"
        echo "TEST" | tee filez{1,2,3}
done
    
por Sergiy Kolodyazhnyy 08.06.2015 / 15:40
1

você pode tentar este script python

import os
def main():
    a = 100
    while a>1:
        os.chdir(os.path.expanduser("~/s000"+a))
        do your work here
        a = a-1
if __name__ == "__main__":
    main()

onde o loop while muda para o diretório até que seja igual a 1. e você pode alterar o valor de um de acordo com seu desejo e, em "faça seu trabalho aqui", escreva o que deseja fazer.

    
por bolzano 08.06.2015 / 15:35
0

O programa sempre escreve Output , mas você não precisa sair dessa forma. Se as configurações do programa forem controladas a partir da linha de comando, você pode simplesmente executar o programa e renomear a saída assim que terminar:

for dirname in 'ls -d s*'
do
    myprogram "$dirname"
    mv Output Output-"$dirname"
done

É claro que não sei quais argumentos de parâmetro seu programa aceita, porque você não diz. Se ele realmente lê muitos arquivos, ainda faz sentido ter diretórios separados. Mas "o nome da saída é fixo" não é, por si só, motivo para todos os problemas.

PS. Não use parênteses em seus nomes de arquivos. Eles têm um significado especial para o shell e confundem seus scripts, a menos que você saiba como lidar com eles.

    
por alexis 08.06.2015 / 17:11