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

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

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

Является ли это проблемой конфигурации?

1
задан 14 June 2013 в 01:06

3 ответа

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

find . -name '*.xml'

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

107
ответ дан 24 May 2018 в 21:05
  • 1
    Он ищет рекурсивно требуемый файл в каталоге, внедренном в текущий каталог. В моем случае он просто проверяется только в текущем каталоге, не проверял подкаталог. – mostafiz rahman 1 October 2014 в 01:24
  • 2
    @mostafiz, вам нужно указать часть * * .xml. Я отредактирую свой ответ. – KaeruCT 1 October 2014 в 19:39
  • 3
    Фактически я искал файлы .php в текущем каталоге. Но он возвратил только файлы .php в текущем каталоге, не искал рекурсивно в подкаталогах. Вот почему я спрашиваю, ищет ли команда find рекурсивно или нет. – mostafiz rahman 1 October 2014 в 21:52
  • 4
    @mostafiz, команда find ищет рекурсивно. Если вы не укажете параметр, я думаю, ваша оболочка может сделать расширение на *, поэтому оно будет соответствовать файлам в текущем каталоге. – KaeruCT 2 October 2014 в 00:38
  • 5
    Отлично! Возможно, я ошибся. Теперь он работает отлично! – mostafiz rahman 2 October 2014 в 19:02

Попробуйте выполнить эту команду:

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

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

11
ответ дан 24 May 2018 в 21:05

bash

Используя опцию globstar shell, мы можем использовать рекурсивное globbing ./**/*

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

Python

Хотя 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))
1
ответ дан 24 May 2018 в 21:05

Другие вопросы по тегам:

Похожие вопросы: