trouver non récursif lorsque le fichier est en haut

8

Imaginez un arbre source. Il y a des fichiers xml partout.

Mais comme il y a un XYZ.xml à la racine de cet arbre, il ne trouvera pas mes fichiers xml.

find -iname *.xml

Retour

./XYZ.xml

au lieu de

./XYZ.xml
./a/b/c/bob.xml
./b/d/top.xml
Olivier Toupin
la source
1
De man find: Veuillez noter que vous devez bien sûr citer des modèles, sinon le shell développera tous les caractères génériques en eux.
artdanil

Réponses:

18
find -iname '*.xml'

Dans le cas contraire, votre shell se dilate *.xmlà XYZ.xml, et la commande qui est exécuté en réalité

find -iname XYZ.xml

La raison pour laquelle cela fonctionne s'il n'y a pas de fichiers XML dans le répertoire courant est que les shells laissent généralement les caractères génériques non développés s'ils ne correspondent à rien. En général, chaque fois que vous voulez wildcards être élargi par un programme autre que le shell (par exemple par find, tar, scp, etc.) dont vous avez besoin de les citer de sorte que le shell ne tentera pas de les développer lui - même.

cjm
la source
1
Thx, c'est si simple, mais je me demande comment contourner cela depuis des mois. J'ai trouvé ça vraiment bizarre, et c'était un comportement très incohérent, mais maintenant je comprends puisque ce n'est pas trouvé, mais la faute de bash.
Olivier Toupin
2
Ce n'est pas la "faute" de bash en soi, mais la vôtre pour ne pas avoir cité les caractères génériques que vous vouliez passer comme arguments. Cela vaut pour tous les programmes qui acceptent l'entrée shell. Le shell les développe en globes à moins qu'ils ne soient cités ou échappés.
Caleb
1
Je suppose qu'Olivier voulait dire cela dans le sens que c'est une question de bash, pas de find.
utilisateur inconnu
6

Vous devez citer votre argument comme ceci:

find ./ -name '*.xml'

afin qu'il soit passé à rechercher au lieu d'être développé par le shell, puis passé à rechercher en tant que version développée.

Caleb
la source
1
Ok, donc si *.xmlne correspond à rien dans le répertoire courant, il est transmis littéralement, c'est pourquoi cela fonctionne dans l'autre cas. Réponse très utile.
Eric Wilson
1

Les caractères génériques sont développés par le shell, pas par la commande. findest l'une des rares commandes qui effectue une correspondance générique similaire à celle du shell, en son temps.

Lorsque vous exécutez ls *.xml, le shell se développe d'abord *.xmlà la liste des fichiers correspondants, par exemple file1.xml file2.xml file3.xml, puis le shell appelle lsavec la liste d'arguments résultante file1.xml file2.xml file3.xml. C'est pourquoi vous voyez la même liste de noms de fichiers avec echo *.xml, même si elle echone sait rien des fichiers et ne se soucie pas de savoir si ses arguments sont des noms de fichiers.

Lorsque vous exécutez find . -name "*.xml":

  1. Le shell analyse la ligne de commande pour reconnaître les caractères spéciaux et le diviser en mots et en ponctuation. Ici , il y a juste une liste de mots find, ., -name, *.xml*est cité. Puisque *est cité, c'est un caractère ordinaire en ce qui concerne le shell.
  2. Le shell exécute la commande findavec la liste d'arguments spécifiée: ., -name, *.xml.
  3. findrecherche les fichiers dont le nom correspond au modèle *.xmldans n'importe quel répertoire du répertoire courant.

Lorsque vous exécutez find . -name *.xmlet qu'aucun fichier ne correspond *.xml:

  1. Le shell analyse la ligne de commande pour reconnaître les caractères spéciaux et le diviser en mots et en ponctuation. Ici , il y a juste une liste de mots find, ., -name, *.xmloù l' *on ne cite.
  2. Puisque le mot *.xmlcontient un caractère générique non cité, le shell effectue la génération du nom de fichier. Puisqu'il n'y a aucun nom de fichier correspondant, le modèle reste non développé.
  3. Le shell exécute la commande findavec la liste résultante des arguments, ce qui est ., -name, *.xml.
  4. findrecherche les fichiers dont le nom correspond au modèle *.xmldans n'importe quel répertoire du répertoire courant.

Lorsque vous exécutez find . -name *.xmlet que le répertoire actuel contient file1.xml, file2.xmlet file3.xml:

  1. Le shell analyse la ligne de commande pour reconnaître les caractères spéciaux et le diviser en mots et en ponctuation. Ici , il y a juste une liste de mots find, ., -name, *.xmloù l' *on ne cite.
  2. Puisque le mot *.xmlcontient un caractère générique non cité, le shell effectue la génération du nom de fichier: *.xmlest remplacé par la liste des noms de fichiers correspondants.
  3. Le shell exécute la commande findavec la liste résultante des arguments, ce qui est ., -name, file1.xml, file2.xml, file3.xml.
  4. findse plaint d'une erreur de syntaxe lorsqu'elle atteint file2.xml.

Lorsque vous exécutez find . -name *.xmlet que le répertoire actuel contient un seul fichier correspondant file.xml:

  1. Le shell analyse la ligne de commande pour reconnaître les caractères spéciaux et le diviser en mots et en ponctuation. Ici , il y a juste une liste de mots find, ., -name, *.xmloù l' *on ne cite.
  2. Puisque le mot *.xmlcontient un caractère générique non cité, le shell effectue la génération du nom de fichier: *.xmlest remplacé par la liste des noms de fichiers correspondants.
  3. Le shell exécute la commande findavec la liste résultante des arguments, ce qui est ., -name, file.xml.
  4. findvoit une commande parfaitement valide, mais ce n'est probablement pas ce que vous vouliez: findon lui dit de rechercher les fichiers appelés file.xmldans n'importe quel répertoire, de ne rechercher aucune correspondance de fichier *.xml.

(L'évaluation et l'expansion de Shell ont beaucoup d'autres fonctionnalités. Je n'ai mentionné que celles qui sont pertinentes ici.)

(Ce que je décris est le comportement par défaut des shells les plus courants: sh, bash, dash, ksh,… Certains shells peuvent être configurés pour afficher une erreur au lieu d'exécuter une commande avec des caractères génériques non développés ou pour étendre les caractères génériques non correspondants à un vide Aucun de ceux-ci ne serait utile ici.)

Gilles 'SO- arrête d'être méchant'
la source
-1

Cela fonctionne sur Solaris 10:

find /directory-to-search/* -prune -name "*gz"

user32445
la source
Cela ne rechercherait pas les noms se terminant par .xml.
Kusalananda
-2

S'il vous plaît essayez:

find ./ -name *.xml
Tok
la source
Je viens d'essayer ça, même résultat.
Eric Wilson
Je l'ai essayé et ça marche. Sur GNU bash 4.2.8
bbaja42
3
Cela ne fonctionne pas lorsque le glob correspond à quelque chose dans le répertoire courant. C'est la mauvaise syntaxe! Le *doit toujours être cité ou échappé pour le passer à trouver.
Caleb