L'itération récursive de fichiers dans un répertoire peut facilement être effectuée par:
find . -type f -exec bar {} \;
Cependant, ce qui précède ne fonctionne pas pour les choses plus complexes, où beaucoup de branches conditionnelles, de boucles, etc. doivent être effectuées. J'ai utilisé cela pour ce qui précède:
while read line; do [...]; done < <(find . -type f)
Cependant, il semble que cela ne fonctionne pas pour les fichiers contenant des caractères obscurs:
$ touch $'a\nb'
$ find . -type f
./a?b
Existe-t-il une alternative qui gère bien ces personnages obscurs?
find ... -exec bash -c 'echo filename is in \$0: "$0"' {} \;
est une meilleure façon de le faire.read line
àIFS= read -r line
. Le seul personnage qui le cassera alors est une nouvelle ligne.-d $'\0'
est préférable.Réponses:
Encore une autre utilisation pour la sécurité
find
:(Cela fonctionne avec n'importe quel POSIX
find
, mais la partie shell nécessite bash. Avec * BSD et GNU find, vous pouvez utiliser à la-print0
place de-exec printf '%s\0' {} +
, ce sera légèrement plus rapide.)Cela permet d'utiliser une entrée standard dans la boucle, et cela fonctionne avec n'importe quel chemin.
la source
do echo "Filename is '$REPLY'"
Cela est aussi simple que:
Ou...
la source
L'approche la plus simple (mais sûre) consiste à utiliser le globbing shell:
Pour faire la récurrence ci-dessus dans des sous-répertoires (en bash), vous pouvez utiliser l'
globstar
option; également définidotglob
pour correspondre aux fichiers dont le nom commence par.
:Attention, jusqu'à bash 4.2, se
**/
reproduit en liens symboliques vers des répertoires. Depuis bash 4.3,**/
récursif uniquement dans les répertoires, commefind
.Une autre solution courante consiste à utiliser
find -print0
avecxargs -0
:Notez que le
h:/g
est en fait correct car le nom de fichier contient un\r
.la source
C'est un peu difficile de faire votre boucle de lecture de manière portable, mais pour bash en particulier, vous pouvez essayer quelque chose comme ça .
Portion pertinente:
Cela indique
find
d'imprimer sa sortie délimitée par des caractères NUL (0x00) etread
de récupérer les lignes délimitées NUL (-d $'\0'
) sans gérer les barres obliques inverses comme des échappements pour les autres caractères (-r
) et de ne pas séparer les mots sur les lignes (IFS=
). Étant donné que 0x00 est un octet qui ne peut pas se produire dans les noms de fichiers ou les chemins d'accès sous Unix, cela devrait gérer tous vos problèmes de noms de fichiers étranges.la source
-d ''
est équivalent à-d $'\0'
.