So suchen Sie rekursiv nach Dateien in Unterverzeichnissen

117

Ich versuche, nach allen XMLDateien in einem bestimmten Verzeichnis und allen (rekursiven) Unterverzeichnissen darin zu suchen .

ls -R *.xmllistet nur Dateien im aktuellen Verzeichnis auf. Ich bin mir ziemlich sicher, dass die Unterordner selbst mehrere .xmlDateien haben, aber keine werden angezeigt.

Ist das ein Konfigurationsproblem?

Shamim Hafiz
quelle
2
Sie können tunls -R | grep .xml
Nikos

Antworten:

90

Versuchen Sie es mit Suchen

sudo find . -print | grep -i '.*[.]xml'
Mitch
quelle
4
ist das sudo muss, oder ist es da, um Super-User-Rechte zu gewährleisten?
Shamim Hafiz
4
Ich lasse dich entscheiden. Sudo , kein Sudo .
Mitch
6
Nur aus Interesse. Was ist der Vorteil von findover ls -R?
don.joey
1
@ don.joey Dies könnte dazu beitragen, stackoverflow.com/questions/13830036/…
Mitch
10
-1 zum Mischen findund grep, wenn findFilterung mit Regexen und Globs möglich ist, und nicht mit find's -print0und grep ' s , -zwenn Sie mischen müssen.
muru
147

Du kannst es nur mit find machen :

find . -name '*.xml'

.ist das aktuelle Verzeichnis. Wenn Sie in einem anderen Verzeichnis suchen müssen, ersetzen Sie es .durch den Verzeichnispfad.

KaeruCT
quelle
2
Sucht rekursiv nach der erforderlichen Datei in dem Verzeichnis, das sich im aktuellen Verzeichnis befindet. In meinem Fall wurde nur das aktuelle Verzeichnis eingecheckt, nicht das Unterverzeichnis.
Mostafiz Rahman
1
@mostafiz, du musst den '* .xml'-Teil zitieren. Ich werde meine Antwort bearbeiten.
KaeruCT
1
Eigentlich habe ich nach .phpDateien im aktuellen Verzeichnis gesucht . Es wurden jedoch nur .phpDateien im aktuellen Verzeichnis zurückgegeben und nicht rekursiv in Unterverzeichnissen gesucht. Deshalb frage ich, ob der findBefehl rekursiv sucht oder nicht.
Mostafiz Rahman
3
@mostafiz, der findBefehl sucht rekursiv. Wenn Sie den Parameter nicht in Anführungszeichen setzen, führt Ihre Shell möglicherweise eine Erweiterung der aus *, sodass sie mit den Dateien im aktuellen Verzeichnis übereinstimmt.
KaeruCT
Gut! Vielleicht habe ich einen Fehler gemacht. Jetzt funktioniert es perfekt!
Mostafiz Rahman
13

Versuchen Sie diesen Befehl:

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

lsEs gibt keine Optionen zum Filtern der Ausgabe. Dafür müssten Sie Pipe verwenden. Das übergibt die Ausgabe von lsan grep, das sie dann filtert, um nur die .xmlDateien anzuzeigen.

Rohit Jain
quelle
5
Wie auch immer, um dies zu bekommen, um das Verzeichnis anzuzeigen, aus dem es kam?
AdamO
1
Obligatorischer Link: Warum nicht analysieren ls?
Ruslan
4

bash

Mit der globstarShell-Option können wir rekursives Globbing verwenden./**/*

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 verfügt über ein Modul Find, das die rekursive Durchquerung von Verzeichnisbäumen ermöglicht. Innerhalb der Sonderfunktion find()können wir ein gewünschtes Unterprogramm und das Verzeichnis definieren, das wir durchlaufen möchten, in diesem Beispiel also .. Der Einzeiler in einem solchen Fall wäre:

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

Während Perl ein ganzes Modul für die rekursive Durchquerung von Bäumen hat, hat Python eine nette Funktion walk(), die Teil des osModuls ist und wiederholt Tupel des obersten Pfads, Liste aller Unterverzeichnisse und Liste der Dateinamen zurückgibt. Wir können Folgendes tun:

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

Das könnte als Skript viel ordentlicher sein:

#!/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))

finden

Andere Antworten haben findfür rekursives Durchlaufen erwähnt, und das ist das Werkzeug für den Job. Was erwähnt werden muss, ist die Tatsache, dass findmehrere Befehlszeilenschalter vorhanden sind, um beispielsweise -printfdie Ausgabe im gewünschten Format zu drucken -type f, nur reguläre Dateien zu finden, -inumnach der Inode-Nummer -mtimezu suchen, nach dem Änderungsdatum zu suchen und -exec <command> {} \;einen bestimmten Befehl zum Verarbeiten der Datei auszuführen mit übergebender Datei als Argument (wobei der {}Standardplatzhalter findfür die aktuelle Datei ist), und vielen anderen, lesen Sie bitte die Manpage für find.

Sergiy Kolodyazhnyy
quelle