Выполнить `ls` рекурсивно с подстановочными знаками

Я пытаюсь найти все файлы проекта определенного типа с помощью:

ls -ltR *.mb

Я знаю, что есть файлы, которые я хочу в нескольких папках, но я не получаю результатов обратно. Что я сделал не так?

2 ответа

ls не соответствует шаблонам. Это просто список файлов или папок во входных аргументах. *.mb расширяется оболочкой перед передачей ls поэтому, если нет файлов с именем *.mb в текущем каталоге ничего не выводится, иначе будут выводиться только файлы в текущем каталоге

Стандартный способ рекурсивного перечисления состоит в использовании find

find . -name '*.mb' -type f -printf "%-.22T+ %M %n %-8u %-8g %8s %Tx %.8TX %p\n" | sort | cut -f 2- -d ' '

Таким образом, вы можете настроить формат списка вывода, как вы хотите. См. Список файлов по дате последнего редактирования


Альтернативный способ заключается в использовании globstar который может быть включен с shopt -s globstar

ls -ltR **/*.mb

Первый **/ будет соответствовать любым произвольным путям подкаталогов. затем *.mb с соответствием ваших файлов в этих каталогах

  • globstar

    Если установлено, шаблон ** используемый в контексте расширения имени файла будет соответствовать всем файлам и нулю или большему количеству каталогов и подкаталогов. Если шаблон сопровождается /, совпадают только каталоги и подкаталоги.

https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html

У @phuclv есть два хороших варианта. Когда мне нужно сделать подобное, я обычно передаю вывод команды ls в grep следующим образом:

ls -ltR | grep .*\.mb

это отправляет вывод ls на вход grep вместо вывода на stdout, а grep выводит только те строки, которые содержат хотя бы одно совпадение для регулярного выражения.

Регулярное выражение

.*\.mb

можно объяснить как:

.: match any character
*: preceding character or group should appear 0 or more times
\.mb: literally .mb
Другие вопросы по тегам