Problème d’utilisation de “find” dans les scripts shell

Au retour, j’ai écrit un script shell qui exécute automatiquement un script python sur tout fichier c ++ qu’il peut trouver dans un répertoire spécifié. Je l’ai testé, ça a bien fonctionné, je l’ai enregistré et j’ai oublié; Le problème est que je suis revenu pour l’utiliser et rencontré un problème (il s’avère que je ne l’ai pas assez testé hein?).

Quoi qu’il en soit, les chemins de répertoire source que je testais auparavant n’avaient aucun espace, par exemple

/somedirectory/subfolder/src/ 

Mais quand j’essaie d’exécuter le script en utilisant un chemin avec des espaces, par exemple

 /Documents\ and\ Settings/subfolder/src/ 

Ça ne marche pas

J’ai trouvé où est le problème, mais je ne sais pas comment le réparer. Voici le code à l’origine du problème:

 names=( $(find "${SOURCE_ROOT_DIRECTORY}" -regex "[A-Za-z0-9]*.*\(cpp\|h\|cc\)$")) 

L’expression régulière fonctionne avec des chemins sans espaces. Je ne suis donc pas sûr qu’il y ait un problème avec l’expression régulière ou si la commande “find” s’arrête lorsqu’elle rencontre un espace.

Quelqu’un peut-il aider?

find ne s’arrête pas quand il frappe des fichiers avec des espaces dans leurs noms. Le problème se produit lorsque vous essayez de les stocker en tant qu’éléments dans un tableau.

Remplacez IFS par le caractère de nouvelle ligne (par défaut, il s’agit d’espace):

 #change IFS OLDIFS=$IFS IFS=$'\n' #run find names=($(find . -regex "[A-Za-z0-9]*.*\(cpp\|h\|cc\)$")) #restore IFS IFS=$OLDIFS #test out the array echo "size: ${#names[@]}" for i in "${names[@]}" do echo "$i" done 

Le modèle d’utilisation canonique est le suivant:

 find subfolder/ -type f -name '*.cpp' -print0 | xargs -0rn1 myscript.py 

Cela a toutes les cloches et les sifflets, vous pouvez probablement faire sans -type f et peut-être certains des drapeaux xargs

vous pouvez utiliser read

 while read -r file; do names+=("$file") done < <(find "${SOURCE_ROOT_DIRECTORY}" -regex "[A-Za-z0-9]*.*\(cpp\|h\|cc\)$") 

un petit test

 $ mkdir -p /tmp/test && cd $_ $ touch foo bar "ab cd" $ ls ab cd bar foo $ while read -r file; do names+=("$file"); done < <(find /tmp/test -type f); $ echo ${#names[@]} 3 $ for file in "${names[@]}"; do echo "$file"; done; /tmp/test/ab cd /tmp/test/bar /tmp/test/foo $ unset names file