web-dev-qa-db-fra.com

Bash For-Loop sur les répertoires

Contexte rapide:

$ ls src
file1  file2  dir1  dir2  dir3

Scénario:

#!/bin/bash

for i in src/* ; do
  if [ -d "$i" ]; then
    echo "$i"
  fi
done

Production:

src/dir1
src/dir2
src/dir3

Cependant, je veux qu'il se lise:

dir1
dir2
dir3

Maintenant je me rends compte que je pourrais sed/awk la sortie pour supprimer "src /" mais je suis curieux de savoir s'il existe une meilleure façon de procéder. Peut-être utiliser à la place une boucle find + while.

32
BassKozz

Faites ceci à la place pour la ligne echo:

 echo $(basename "$i")
21
Gonzalo

Pas besoin de bifurquer un processus externe:

echo "${i##*/}"

Il utilise le "supprimer le préfixe correspondant le plus long" expansion des paramètres . Le */ est le modèle, il supprimera donc tout depuis le début de la chaîne jusqu'à la dernière barre oblique. S'il n'y a pas de barre oblique dans la valeur de $i, alors c'est la même chose que "$i".

Cette extension de paramètre particulière est spécifiée dans POSIX et fait partie de l'héritage du Bourne Shell d'origine. Il est pris en charge dans tous les shells de type Bourne ( sh , ash , tiret , ksh , bash , zsh , etc.). De nombreux shells riches en fonctionnalités (par exemple ksh , bash , et zsh ) a d'autres extensions qui peuvent gérer encore plus sans impliquer des processus externes.

13
Chris Johnsen

Si vous faites un cd au début du script, il doit être annulé à la fin du script.

#!/bin/bash

cd src
for i in * ; do
  if [ -d "$i" ]; then
    echo "$i"
  fi
done
8
Mark Ransom

Utilisez basename comme:

if [ -d "$i" ]; then
    basename "$i"
fi
5
codaddict