3 votes

Changement séquentiel de répertoire et exécution d'un script.

Je ne parviens pas à trouver la moindre aide à ce sujet. J'ai, disons, 2000 répertoires dans lesquels je dois exécuter un programme spécifique. En raison des limitations du programme, il ne peut pas simplement écrire 'Output1', 'Output2', 'Output3', etc. Il doit écrire 'Output' comme fichier de sortie et écrasera tout autre fichier nommé 'Output', d'où la nécessité d'un répertoire pour chaque instance unique du programme. Ce dont j'ai besoin est quelque chose comme ceci

Avec s étant le préfixe du répertoire. I. E., s0001, s0002....s2000 étant les noms des répertoires.

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

et que cette commande en boucle s'arrête après

cd s2000

. J'essayais de le faire fonctionner par un

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

mais en vain.

Toute aide est appréciée.

4voto

Stewart Points 1385

Les détails dépendent de votre configuration. Si le répertoire parent ne contient que les répertoires enfants s0001 à s2000, il vous suffit de les parcourir et de lancer le programme dans chacun d'eux :

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

Cela va se déplacer dans chaque répertoire et lancer run_program . Une fois que c'est terminé, il revient en arrière.

Si vous avez besoin de spécifier une gamme de répertoires, utilisez ceci à la place :

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

Enfin, si vous souhaitez lancer tous les processus simultanément (ce qui ne risque pas de mettre votre ordinateur à genoux), utilisez la fonction & :

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

Les anciennes versions de bash ne se développent pas {001..002} como 001 002 mais comme 1 2 à la place. Si votre bash ne supporte pas cela, utilisez cette approche à la place :

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

L'astuce consiste à générer les nombres entre 1 et 2000 en utilisant seq et ensuite utiliser printf pour ajouter des 0 de tête si nécessaire.

2voto

Sergiy Kolodyazhnyy Points 97292

Voici un bash script. N'hésitez pas à l'adapter en fonction de vos besoins.

#!/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

1voto

bolzano Points 1432

Vous pouvez essayer ce Python script

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()

où la boucle while change le répertoire jusqu'à ce qu'il soit égal à 1. et vous pouvez changer la valeur de a selon votre souhait et à "faites votre travail ici", écrivez ce que vous voulez faire.

0voto

alexis Points 1018

Le programme écrit toujours Output mais vous n'êtes pas obligé de laisser les choses ainsi. Si les paramètres du programme sont contrôlés à partir de la ligne de commande, vous pouvez simplement exécuter le programme et renommer la sortie dès qu'il se termine :

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

Bien sûr, je ne sais pas quels arguments de paramètres votre programme accepte, car vous ne le dites pas. S'il lit réellement à partir de nombreux fichiers, il est toujours logique d'avoir des répertoires séparés. Mais "le nom de la sortie est fixe" n'est pas en soi une raison pour se donner tout ce mal.

PS. N'utilisez pas de parenthèses dans vos noms de fichiers. Elles ont une signification spéciale pour le Shell et embrouillent vos Shell à moins que vous ne sachiez comment les gérer.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X