Como procurar arquivos recursivamente em subdiretórios

117

Estou tentando procurar todos os XMLarquivos em um diretório específico e todos os subdiretórios (recursivamente) dentro dele.

ls -R *.xmlestá listando apenas arquivos no diretório atual. Tenho certeza de que as próprias subpastas têm vários .xmlarquivos, mas nenhum está aparecendo.

Isso é um problema de configuração?

Shamim Hafiz
fonte
2
Você pode fazerls -R | grep .xml
Nikos

Respostas:

90

Tente usar Localizar

sudo find . -print | grep -i '.*[.]xml'
Mitch
fonte
4
o sudo deve ou existe para garantir privilégios de superusuário?
Shamim Hafiz
4
Eu deixei você decidir. Sudo , não Sudo .
Mitch
6
Apenas por interesse. Qual é a vantagem do findexcesso ls -R?
Don.joey
1
@ don.joey Isso pode ajudar stackoverflow.com/questions/13830036/…
Mitch
10
-1 para mixar finde grep, quando é findpossível filtrar usando regexes e globs, e não usar find's -print0e grep's -zquando você precisa misturar.
Muni
147

Você pode fazer isso apenas com localização :

find . -name '*.xml'

.é o diretório atual. Se você precisar procurar em outro diretório, substitua .pelo caminho do diretório.

KaeruCT
fonte
2
Ele procura o arquivo necessário recursivamente no diretório raiz do diretório atual. No meu caso, apenas fez check-in apenas no diretório atual, não verificou o subdiretório.
Mostafiz Rahman
1
@mostafiz, você precisa citar a parte '* .xml'. Vou editar minha resposta.
KaeruCT
1
Na verdade, eu procurei por .phparquivos no diretório atual. Mas ele retornou apenas .phparquivos no diretório atual, não pesquisou recursivamente nos subdiretórios. É por isso que estou perguntando se o findcomando procura recursivamente ou não.
Mostafiz Rahman
3
@mostafiz, o findcomando pesquisa recursivamente. Se você não citar o parâmetro, acho que seu shell pode fazer uma expansão no *, portanto, ele corresponderá aos arquivos no diretório atual.
KaeruCT
Tudo certo! Pode ser que eu tenha cometido algum erro. Agora está funcionando perfeitamente!
Mostafiz Rahman
13

Tente este comando:

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

lsnão tem opções para filtrar a saída. Para isso você precisaria usar cachimbo. Isso passa a saída de lspara grep, que os filtra para mostrar apenas os .xmlarquivos.

Rohit Jain
fonte
5
Enfim, para que isso mostre o diretório de origem?
AdamO
1
Link obrigatório: por que não analisar ls?
Ruslan
4

bater

Usando a globstaropção shell, podemos fazer uso de globbing recursivo./**/*

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

O Perl possui um módulo Findque permite a travessia recursiva da árvore de diretórios. Dentro da find()função especial , podemos definir uma sub-rotina desejada e o diretório que queremos percorrer, neste exemplo, é isso .. O one-liner nesse caso seria:

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

Pitão

Enquanto o Perl tem um módulo inteiro dedicado à passagem de árvore recursiva, o Python tem uma função elegante walk()que faz parte do osmódulo e retorna repetidamente a tupla do caminho superior, lista de todos os subdiretórios e lista de nomes de arquivos. Podemos fazer o seguinte:

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

Isso pode ser muito mais limpo como um 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))

encontrar

Outras respostas foram mencionadas findpara a travessia recursiva, e essa é a ferramenta essencial para o trabalho. O que precisa ser mencionado é o fato de findhaver várias opções de linha de comando, como -printfimprimir a saída no formato desejado, -type fencontrar apenas arquivos regulares, -inumpesquisar pelo número do inode, -mtimepesquisar pela data da modificação, -exec <command> {} \;executar um comando específico para processar o arquivo com a passagem do arquivo como argumento (onde {}é o findespaço reservado padrão para o arquivo atual) e muitos outros, por isso, leia a página de manual find.

Sergiy Kolodyazhnyy
fonte