Хотя использование findкоманды здесь может быть полезным, сама оболочка предоставляет опции для выполнения этого требования без каких-либо сторонних инструментов. bashОболочка обеспечивает расширенный вариант поддержки Glob с помощью которой вы можете получить имена файлов при рекурсивных путях, матч с расширениями , которые вы хотите.
Расширенная опция - это то, extglobчто нужно установить, используя shoptопцию, как показано ниже. Опции включены с -sподдержкой и отключены с -uфлагом. Кроме того, вы можете использовать несколько опций, то есть, nullglobкогда непревзойденный глобус будет полностью удален, заменен набором нулевых слов. И globstarэто позволяет проходить через все каталоги
shopt -s extglob nullglob globstar
Теперь все, что вам нужно сделать, это сформировать выражение glob для включения файлов определенного расширения, которые вы можете сделать, как показано ниже. Мы используем массив для заполнения результатов глоба, потому что при правильном цитировании и расширении имена файлов со специальными символами останутся нетронутыми и не сломаются из-за разбиения слов оболочкой.
Например, чтобы перечислить все *.csvфайлы в рекурсивных путях
fileList=(**/*.csv)
Опция **состоит в том, чтобы проходить по подпапкам и *.csvрасширять глобально, чтобы включить любой файл упомянутых расширений. Теперь для печати реальных файлов, просто сделайте
printf '%s\n' "${fileList[@]}"
Использование массива и правильное раскрытие в кавычках - правильный путь при использовании в сценариях оболочки, но для интерактивного использования вы можете просто использовать lsвыражение glob как
ls -1 -- **/*.csv
Это вполне может быть расширено для соответствия нескольким файлам, т.е. файлам, заканчивающимся несколькими расширениями (то есть аналогично добавлению нескольких флагов в findкоманду) Например, рассмотрим случай получения всех файлов рекурсивных изображений, например расширений *.gif, *.pngи *.jpgвсе, что вам нужно, это
ls -1 -- **/+(*.jpg|*.gif|*.png)
Это вполне может быть расширено, чтобы иметь отрицательные результаты также. С тем же синтаксисом можно использовать результаты glob для исключения файлов определенного типа. Предположим, вы хотите исключить имена файлов с расширениями выше, вы можете сделать
excludeResults=()
excludeResults=(**/!(*.jpg|*.gif|*.png))
printf '%s\n' "${excludeResults[@]}"
Конструкция !()представляет собой операцию отрицания, которая не включает в себя ни одно из расширений файлов, перечисленных внутри, и |является оператором чередования, аналогичным тому, который используется в библиотеке расширенных регулярных выражений для сопоставления ИЛИ глобанов.
Обратите внимание, что эта расширенная поддержка glob недоступна в оболочке POSIX bourne и является чисто специфической для последних версий bash. Так что, если вы рассматриваете переносимость скриптов, работающих в POSIX и bashоболочках, эта опция не будет правильной.