Jak wyszukiwać pliki rekurencyjnie w podkatalogach

116

Próbuję wyszukać wszystkie XMLpliki w określonym katalogu i wszystkie podkatalogi (rekurencyjnie) w nim zawarte.

ls -R *.xmlwyświetla tylko pliki w bieżącym katalogu. Jestem pewien, że same podfoldery mają kilka .xmlplików, ale żaden z nich się nie pokazuje.

Czy to problem z konfiguracją?

Shamim Hafiz
źródło
2
Możesz zrobićls -R | grep .xml
Nikos

Odpowiedzi:

90

Spróbuj użyć Znajdź

sudo find . -print | grep -i '.*[.]xml'
Mitch
źródło
4
czy sudo musi, czy jest tam, aby zapewnić uprawnienia superużytkownika?
Shamim Hafiz,
4
Pozwalam ci zdecydować. Sudo , No Sudo .
Mitch
6
Po prostu z zainteresowania. Jaka jest przewaga findnad ls -R?
don.joey
1
@ don.joey To może pomóc stackoverflow.com/questions/13830036/…
Mitch
10
-1 do miksowania findoraz grep, kiedy findmożna przeprowadzić filtrowanie przy użyciu zarówno wyrażeń regularnych, jak i globów, a także nieużywając find'i' -print0grep ', -zkiedy trzeba miksować.
muru,
147

Możesz to zrobić tylko z funkcją Znajdź :

find . -name '*.xml'

.jest bieżącym katalogiem. Jeśli chcesz wyszukać w innym katalogu, zastąp .go ścieżką do katalogu.

KaeruCT
źródło
2
Czy rekursywnie szuka wymaganego pliku w katalogu zrootowanym w bieżącym katalogu. W moim przypadku po prostu sprawdził tylko w bieżącym katalogu, nie sprawdził podkatalogu.
Mostafiz Rahman
1
@mostafiz, musisz zacytować część „* .xml”. Zmienię swoją odpowiedź.
KaeruCT
1
Właściwie szukałem .phpplików w bieżącym katalogu. Ale zwrócił tylko .phppliki w bieżącym katalogu, nie przeszukiwał rekurencyjnie w podkatalogach. Dlatego pytam, czy findpolecenie wyszukuje rekurencyjnie, czy nie.
Mostafiz Rahman
3
@mostafiz, findpolecenie wyszukuje rekurencyjnie. Jeśli nie podasz parametru, myślę, że twoja powłoka może dokonać rozszerzenia *, więc będzie pasować do plików w bieżącym katalogu.
KaeruCT
W porządku! Być może popełniłem błąd. Teraz działa idealnie!
Mostafiz Rahman
13

Wypróbuj to polecenie:

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

lsnie ma opcji filtrowania danych wyjściowych. W tym celu musisz użyć rury. To przekazuje dane wyjściowe z lsdo grep, a następnie filtruje je, aby pokazać tylko .xmlpliki.

Rohit Jain
źródło
5
W każdym razie, aby uzyskać to, aby pokazać katalog, z którego pochodzi?
AdamO
1
Link obowiązkowy: dlaczego nie parsować ls?
Ruslan
4

grzmotnąć

Korzystając z globstaropcji powłoki, możemy skorzystać z rekurencyjnego globowania./**/*

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 ma moduł Find, który pozwala na rekurencyjne przechodzenie przez drzewo katalogów. W ramach find()funkcji specjalnej możemy zdefiniować pożądany podprogram i katalog, który chcemy przejść, w tym przykładzie to .. Jednowarstwowy w takim przypadku to:

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

Pyton

Podczas gdy Perl ma cały moduł dedykowany do przechodzenia przez rekurencyjne drzewo, Python ma zgrabną funkcję, walk()która jest częścią osmodułu i wielokrotnie zwraca krotkę najwyższej ścieżki, listę wszystkich podkatalogów i listę nazw plików. Możemy wykonać następujące czynności:

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

Może to być o wiele fajniejsze jako skrypt:

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

odnaleźć

Inne odpowiedzi wspomniano findo rekursywnym przechodzeniu, a to narzędzie do zadania. Należy wspomnieć o tym, że findma wiele przełączników wiersza poleceń, takich jak -printfdrukowanie danych wyjściowych w pożądanym formacie, -type fwyszukiwanie tylko zwykłych plików, -inumwyszukiwanie według numeru i-węzła, -mtimewyszukiwanie według daty modyfikacji, -exec <command> {} \;wykonywanie określonego polecenia w celu przetworzenia pliku z przekazaniem pliku jako argumentu (gdzie {}jest standardowym findsymbolem zastępczym dla bieżącego pliku) i wieloma innymi, więc proszę przeczytać stronę podręcznika dla find.

Sergiy Kolodyazhnyy
źródło