Comment rechercher des fichiers récursivement dans des sous-répertoires

117

J'essaie de rechercher tous les XMLfichiers dans un répertoire particulier et tous les sous-répertoires (récursivement) qu'il contient.

ls -R *.xmlne répertorie que les fichiers du répertoire en cours. Je suis tout à fait sûr, les sous-dossiers eux-mêmes ont plusieurs .xmlfichiers, mais aucun ne s'affiche.

Est-ce un problème de configuration?

Shamim Hafiz
la source
2
Vous pouvez fairels -R | grep .xml
Nikos

Réponses:

90

Essayez d'utiliser Trouver

sudo find . -print | grep -i '.*[.]xml'
Mitch
la source
4
le sudo doit-il ou est-il là pour garantir les privilèges de super utilisateur?
Shamim Hafiz
4
Je vous laisse décider. Sudo , pas de Sudo .
Mitch
6
Juste par intérêt. Quel est l'avantage de findfini ls -R?
don.joey
1
@ don.joey Cela pourrait aider stackoverflow.com/questions/13830036/…
Mitch
10
-1 pour le mélange findet grep, quand findpeut faire le filtrage en utilisant les expressions rationnelles et globs, et non à l' aide findde -print0et grep de -zquand vous avez besoin de mélanger.
muru
147

Vous pouvez le faire avec find only:

find . -name '*.xml'

.est le répertoire en cours. Si vous devez rechercher dans un autre répertoire, remplacez-le .par le chemin du répertoire.

KaeruCT
la source
2
Est-ce qu'il recherche le fichier requis de manière récursive dans le répertoire enraciné dans le répertoire actuel. Dans mon cas, il vient de vérifier uniquement dans le répertoire actuel, mais pas dans le sous-répertoire.
Mostafiz Rahman
1
@mostafiz, vous devez citer la partie '* .xml'. Je vais modifier ma réponse.
KaeruCT
1
En fait, j'ai recherché des .phpfichiers dans le répertoire actuel. Mais il n'a renvoyé que les .phpfichiers du répertoire en cours, sans recherche récursive dans les sous-répertoires. C'est pourquoi je demande si la findcommande est récursive ou non.
Mostafiz Rahman
3
@mostafiz, la findcommande effectue une recherche récursive. Si vous ne citez pas le paramètre, je pense que votre shell peut procéder à une expansion de la *, il correspond donc aux fichiers du répertoire en cours.
KaeruCT
D'accord! Peut-être que j'avais commis une erreur. Maintenant cela fonctionne parfaitement!
Mostafiz Rahman
13

Essayez cette commande:

ls -R | grep '.*[.]xml'

lsn'a pas les options pour filtrer la sortie. Pour cela, vous devez utiliser un tuyau. Cela transmet la sortie de lsà grep, qui les filtre ensuite pour afficher uniquement les .xmlfichiers.

Rohit Jain
la source
5
Quoi qu'il en soit, obtenir ceci pour montrer le répertoire d'où il vient?
AdamO
1
Lien obligatoire: Pourquoi ne pas analyser ls?
Ruslan
4

frapper

En utilisant l' globstaroption shell, nous pouvons utiliser la méthode récursive./**/*

bash-4.3$ shopt -s globstar
bash-4.3$ for i in  ./**/*.xml; do printf "%s\n" "$i" ; done
./adwaita-timed.xml
./bin/hw5/stuff/book/chapter42servletexample/build/web/META-INF/context.xml
./bin/hw5/stuff/book/chapter42servletexample/build/web/WEB-INF/beans.xml
./bin/hw5/stuff/book/chapter42servletexample/build/web/WEB-INF/web.xml

Perl

Perl a un module Findqui permet une traversée récursive de l’arborescence de répertoires. Dans la find()fonction spéciale , nous pouvons définir un sous-programme souhaité et le répertoire que nous voulons parcourir, dans cet exemple .. Le one-liner dans ce cas serait:

bash-4.3$ perl -le 'use File::Find; find(sub{-f && $_ =~ /.xml$/ && print $File::Find::name},".")' 
./adwaita-timed.xml
./CLEAR_DESKTOP/blahblah/hw5/stuff/book/jsf2demo/build/web/WEB-INF/beans.xml
./CLEAR_DESKTOP/blahblah/hw5/stuff/book/jsf2demo/build/web/WEB-INF/web.xml
./CLEAR_DESKTOP/blahblah/hw5/stuff/book/liangweb/build.xml

Python

Alors que Perl a tout un module dédié à la traversée d'arbres récursive, Python a une fonction soignée walk()qui fait partie du osmodule, et renvoie à plusieurs reprises le tuple du chemin le plus haut, la liste de tous les sous-répertoires et la liste des noms de fichiers. Nous pouvons faire ce qui suit:

bash-4.3$ python -c 'import os,sys; [ sys.stdout.write(os.path.join(r,i)+"\n") for r,s,f in os.walk(".") for i in f if i.endswith(".xml") ]' 
./adwaita-timed.xml
./CLEAR_DESKTOP/blahblah/hw5/stuff/book/jsf2demo/build/web/WEB-INF/beans.xml
./CLEAR_DESKTOP/blahblah/hw5/stuff/book/jsf2demo/build/web/WEB-INF/web.xml
./CLEAR_DESKTOP/blahblah/hw5/stuff/book/liangweb/build.xml

Cela pourrait être beaucoup mieux comme script:

#!/usr/bin/env python
import os,sys 
for r,s,f in os.walk("."): 
    for i in f: 
        if i.endswith(".xml") 
             print(os.path.join(r,i))

trouver

D'autres réponses ont été mentionnées findpour la traversée récursive, et c'est l'outil de prédilection pour le travail. Ce qu'il faut mentionner, c’est le fait qu’il findexiste plusieurs commutateurs de ligne de commande, par exemple -printfimprimer la sortie au format souhaité, -type frechercher uniquement les fichiers normaux, -inumrechercher par numéro d’inode, -mtimerechercher par date de modification, -exec <command> {} \;exécuter une commande particulière pour traiter le fichier. en passant le fichier comme argument (où {}est l’ findespace réservé standard pour le fichier actuel), et beaucoup d’autres, merci de lire la page de manuel pour find.

Sergiy Kolodyazhnyy
la source