231 votes

Comment aller dans chaque répertoire et exécuter une commande ?

Comment puis-je écrire un bash script qui passe par chaque répertoire à l'intérieur d'un parent_directory et exécute a commande en chaque répertoire .

La structure des répertoires est la suivante :

parent_directory (le nom peut être n'importe quoi - il ne suit pas un modèle)

  • 001 (les noms des répertoires suivent ce modèle)
    • 0001.txt (les noms de fichiers suivent ce modèle)
    • 0002.txt
    • 0003.txt
  • 002
    • 0001.txt
    • 0002.txt
    • 0003.txt
    • 0004.txt
  • 003
    • 0001.txt

le nombre de répertoires est inconnu.

26voto

gforcada Points 948

Si le dossier de premier niveau est connu, vous pouvez simplement écrire quelque chose comme ceci :

for dir in `ls $YOUR_TOP_LEVEL_FOLDER`;
do
    for subdir in `ls $YOUR_TOP_LEVEL_FOLDER/$dir`;
    do
      $(PLAY AS MUCH AS YOU WANT);
    done
done

Sur le $(PLAY AS MUCH AS YOU WANT) ; vous pouvez mettre autant de code que vous voulez.

Notez que je n'ai fait "cd" sur aucun répertoire.

A la vôtre,

23voto

Idelic Points 4196
for dir in PARENT/*
do
  test -d "$dir" || continue
  # Do something with $dir...
done

7voto

ShitalShah Points 2213

Alors que les one liners sont bons pour une utilisation rapide et sale, je préfère la version ci-dessous plus verbeuse pour écrire des scripts. C'est le modèle que j'utilise qui prend en charge de nombreux cas limites et vous permet d'écrire un code plus complexe à exécuter sur un dossier. Vous pouvez écrire votre code bash dans la fonction dir_command. Ci-dessous, dir_coomand implémente le marquage de chaque dépôt dans git comme exemple. Le reste du scripts appelle dir_command pour chaque dossier dans le répertoire. L'exemple d'itération à travers seulement un ensemble donné de dossiers est également inclus.

#!/bin/bash

#Use set -x if you want to echo each command while getting executed
#set -x

#Save current directory so we can restore it later
cur=$PWD
#Save command line arguments so functions can access it
args=("$@")

#Put your code in this function
#To access command line arguments use syntax ${args[1]} etc
function dir_command {
    #This example command implements doing git status for folder
    cd $1
    echo "$(tput setaf 2)$1$(tput sgr 0)"
    git tag -a ${args[0]} -m "${args[1]}"
    git push --tags
    cd ..
}

#This loop will go to each immediate child and execute dir_command
find . -maxdepth 1 -type d \( ! -name . \) | while read dir; do
   dir_command "$dir/"
done

#This example loop only loops through give set of folders    
declare -a dirs=("dir1" "dir2" "dir3")
for dir in "${dirs[@]}"; do
    dir_command "$dir/"
done

#Restore the folder
cd "$cur"

5voto

Aif Points 4603

Je ne comprends pas l'intérêt du formatage du fichier, puisque vous voulez seulement itérer dans les dossiers... Vous cherchez quelque chose comme ça ?

cd parent
find . -type d | while read d; do
   ls $d/
done

3voto

Dan Bizdadea Points 918

Vous pouvez utiliser

find .

pour rechercher tous les fichiers/répertoires dans le répertoire actuel récursif

Ensuite, vous pouvez envoyer la sortie à la commande xargs comme suit

find . | xargs 'command here'

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X