2011-07-05 4 views
3

J'ai écrit un script shell qui exécute automatiquement un script python sur tous les fichiers C++ qu'il peut trouver dans un répertoire spécifié. Je l'ai testé, ça a bien fonctionné, et je l'ai sauvegardé et oublié; problème est que je suis revenu à l'utiliser et a rencontré un problème (s'avère que je ne l'ai pas testé assez hein?). Quoi qu'il en soit, les chemins du répertoire source que je testais auparavant n'avaient pas d'espaces dans leurs noms, par ex. Mais quand j'essaie d'exécuter le script en utilisant un chemin avec des espaces, par exemple, je ne peux pas exécuter le script.Problème lors de l'utilisation de "find" dans le script shell

/Documents\ and\ Settings/subfolder/src/ 

Cela ne fonctionne pas.

J'ai localisé où le problème est, mais je ne suis pas sûr de savoir comment le résoudre. Voici le code 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, donc je ne sais pas s'il y a un problème avec l'expression régulière, ou si la commande se arrête « trouver » lorsqu'il rencontre un espace.

Quelqu'un peut-il aider?

Répondre

2

find ne pas "stop" quand il frappe des fichiers avec des espaces. Le problème se produit lorsque vous essayez de les stocker en tant qu'éléments dans un tableau.

changement IFS au caractère de nouvelle ligne (par défaut, il est l'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 
+0

Ceci a été la solution qui a fonctionné pour m e, donc c'est ma réponse acceptée :) – BigStuuu

1

vous pouvez utiliser dans leurs noms lire

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 
+0

Fonctionne probablement bien pour les noms sans saut de ligne dans le chemin ... –

2

Le modèle d'utilisation canonique est:

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

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

Questions connexes