Je veux utiliser find
pour rechercher des fichiers dans un ensemble de dossiers restreints par des caractères génériques, mais où il y a des espaces dans le nom du chemin.
Depuis la ligne de commande, c'est facile. Les exemples suivants fonctionnent tous.
find te*/my\ files/more -print
find te*/'my files'/more -print
find te*/my' 'files/more -print
Ceux-ci trouveront des fichiers dans, par exemple, terminal/my files/more
et tepid/my files/more
.
Cependant, j'ai besoin que cela fasse partie d'un script; ce dont j'ai besoin est quelque chose comme ceci:
SEARCH='te*/my\ files/more'
find ${SEARCH} -print
Malheureusement, quoi que je fasse, je ne semble pas être capable de mélanger les caractères génériques et les espaces dans une find
commande au sein d'un script. L'exemple ci-dessus renvoie les erreurs suivantes (notez le doublement inattendu de la barre oblique inverse):
find: ‘te*/my\\’: No such file or directory
find: ‘files/more’: No such file or directory
Essayer d'utiliser des guillemets échoue également.
SEARCH="te*/'my files'/more"
find ${SEARCH} -print
Cela renvoie les erreurs suivantes, après avoir ignoré la signification des guillemets:
find: ‘te*/'my’: No such file or directory
find: ‘files'/more’: No such file or directory
Voici un autre exemple.
SEARCH='te*/my files/more'
find ${SEARCH} -print
Comme prévu:
find: ‘te*/my’: No such file or directory
find: ‘files/more’: No such file or directory
Chaque variation que j'ai essayée renvoie une erreur.
J'ai une solution de contournement, qui est potentiellement dangereuse car elle renvoie trop de dossiers. Je convertis tous les espaces en point d'interrogation (caractère générique à un caractère) comme ceci:
SEARCH='te*/my files/more'
SEARCH=${SEARCH// /?} # Convert every space to a question mark.
find ${SEARCH} -print
C'est l'équivalent de:
find te*/my?files/more -print
Cela renvoie non seulement les dossiers corrects mais aussi terse/myxfiles/more
, ce qui n'est pas censé le faire.
Comment puis-je réaliser ce que j'essaie de faire? Google ne m'a pas aidé :(
SEARCH: command not found
l'find -print
exécution de la commande .find "${SEARCH}" -print
?te*/'my files'/more
.Réponses:
La même commande devrait fonctionner correctement dans un script:
Si vous devez l' avoir comme variable, cela devient un peu plus complexe:
ATTENTION:
L'utilisation de ce
eval
type n'est pas sûre et peut entraîner l'exécution de code arbitraire et potentiellement dangereux si les noms de vos fichiers peuvent contenir certains caractères. Voir bash FAQ 48 pour plus de détails.Il vaut mieux passer le chemin en argument:
Une autre approche consiste à éviter
find
complètement et à utiliser les fonctionnalités de globbing étendues et les globs de bash:L'
globstar
option bash vous permet d'utiliser**
pour faire correspondre de manière récursive:Pour le faire agir à 100% comme trouver et inclure des fichiers dot (fichiers cachés), utilisez
Vous pouvez même
echo
les directement sans la boucle:la source
Que diriez-vous des tableaux?
(*)
se développe dans un tableau de tout ce qui correspond au caractère générique. Et se"${SEARCH[@]}"
développe dans tous les éléments du tableau ([@]
), chacun étant cité individuellement.Tardivement, je me rends compte qu’elle devrait en être capable. Quelque chose comme:
la source
INPUTPATH='te*/my files/more
etSEARCH=(${INPUTPATH})
. Peu importe comment je modifie ma façon de procéder, je me retrouve toujours avec un résultat non fonctionnel. Cela semble impossible!find
le-path
filtre de? Il utilise des caractères génériques et n'a certainement pas besoin d'extension.-path
. Au cours des 10 dernières minutes, j'ai trouvé la réponse: utilisezeval
! Cela semble être plus simple que-path
.J'ai enfin trouvé la réponse.
Ajoutez une barre oblique inverse à tous les espaces:
À ce stade,
SEARCH
contientte*/my\ files/more
.Ensuite, utilisez
eval
.C'est si simple! L'utilisation
eval
contourne l'interprétation qui${SEARCH}
provient d'une variable.la source