Як шукати файли рекурсивно в підкаталогах


116

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

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

Це проблема з конфігурацією?


2
Можна зробитиls -R | grep .xml
Нікос

Відповіді:


90

Спробуйте використовувати Find

sudo find . -print | grep -i '.*[.]xml'

4
судо повинен чи він є, щоб забезпечити привілеї супер користувача?
Шамім Хафіз

4
Я даю вам вирішити. Судо , немає судо .
Мітч

6
Просто з інтересу. Що таке перевага findнад ls -R?
don.joey

1
@ Don.joey Це може допомогти stackoverflow.com/questions/13830036 / ...
Мітч

10
-1 для змішування findі grep, коли findможна фільтрувати, використовуючи як регулярні вирази, так і глобуси, а не використовувати find's -print0і grep's, -zколи вам потрібно змішати.
муру

147

Ви можете це зробити лише з пошуку :

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параметр shell, ми можемо скористатися рекурсивним глобулюванням./**/*

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.