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


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'

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


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.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.