Как искать файлы рекурсивно в подкаталогах

117

Я пытаюсь найти все XMLфайлы в определенном каталоге и все подкаталоги (рекурсивно) внутри него.

ls -R *.xmlтолько список файлов в текущем каталоге. Я совершенно уверен, что у самих подпапок есть несколько .xmlфайлов, но ни один не обнаруживается.

Это проблема конфигурации?

Шамим Хафиз
источник
2
Вы можете сделатьls -R | grep .xml
Никос

Ответы:

90

Попробуйте использовать Find

sudo find . -print | grep -i '.*[.]xml'
Митч
источник
4
должен ли sudo или для обеспечения привилегий суперпользователя?
Шамим Хафиз
4
Я позволю тебе решить. Судо , Нет Судо .
Митч
6
Просто из интереса. В чем преимущество findперед ls -R?
don.joey
1
@ don.joey Это может помочь stackoverflow.com/questions/13830036/…
Митч
10
-1 для смешивания findи grep, когда findможно выполнять фильтрацию, используя как регулярные выражения, так и глобусы, и не использовать finds -print0и grep, -zкогда вам нужно смешать.
Муру
147

Вы можете сделать это только с помощью find :

find . -name '*.xml'

.это текущий каталог. Если вам нужно выполнить поиск в другом каталоге, замените его .на путь к каталогу.

KaeruCT
источник
2
Выполняет ли он поиск необходимого файла рекурсивно в каталоге с корневым каталогом в текущем каталоге. В моем случае он только проверил только в текущем каталоге, не проверял подкаталог.
Мостафиз Рахман
1
@mostafiz, вам нужно процитировать часть '* .xml'. Я отредактирую свой ответ.
KaeruCT
1
На самом деле я искал .phpфайлы в текущем каталоге. Но он возвращал только .phpфайлы в текущем каталоге, не проводил рекурсивный поиск в подкаталогах. Вот почему я спрашиваю, findвыполняет ли команда рекурсивный поиск или нет.
Мостафиз Рахман
3
@mostafiz, findкоманда ищет рекурсивно. Если вы не заключите в кавычки параметр, я думаю, что ваша оболочка может выполнить расширение *, поэтому она будет соответствовать файлам в текущем каталоге.
KaeruCT
Хорошо! Может быть, я сделал какую-то ошибку. Теперь это работает отлично!
Мостафиз Рахман
13

Попробуйте эту команду:

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

lsне имеет параметров для фильтрации вывода. Для этого вам нужно будет использовать трубу. Это передает выходные данные из lsв grep, который затем фильтрует их, чтобы показать только .xmlфайлы.

Рохит Джайн
источник
5
В любом случае, чтобы показать каталог, из которого он пришел?
AdamO
1
Обязательная ссылка: почему бы не разобрать ls?
Руслан
4

удар

Использование globstarопции оболочки, мы можем использовать рекурсивное глобирование./**/*

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 есть модуль Find, который позволяет выполнять рекурсивный обход дерева каталогов. Внутри специальной find()функции мы можем определить требуемую подпрограмму и каталог, который мы хотим пройти, в этом примере это .. Однострочник в таком случае будет:

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

питон

В то время как Perl имеет целый модуль, предназначенный для рекурсивного обхода дерева, Python имеет аккуратную функцию, walk()которая является частью osмодуля, и многократно возвращает кортеж верхнего пути, список всех подкаталогов и список имен файлов. Мы можем сделать следующее:

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

Это может быть гораздо лучше, как сценарий:

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

находить

Другие ответы были упомянуты findдля рекурсивного обхода, и это инструмент перехода к работе. Что нужно упомянуть, так это тот факт, что findимеется несколько ключей командной строки, например, -printfдля вывода выходных данных в нужном формате, -type fдля поиска только обычных файлов, -inumдля поиска по номеру индекса, -mtimeдля поиска по дате изменения, -exec <command> {} \;для выполнения определенной команды для обработки файла. с передачей файла в качестве аргумента (где {}стандартная findметка-заполнитель для текущего файла) и многими другими, поэтому, пожалуйста, прочитайте страницу руководства для find.

Сергей Колодяжный
источник