Хоча використовуючи 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)
Це дуже добре розширити, щоб мати і негативні результати. З тим самим синтаксисом можна використовувати результати глобуса для виключення файлів певного типу. Припустимо, ви хочете виключити імена файлів із розширеннями вище, ви могли б зробити
excludeResults=()
excludeResults=(**/!(*.jpg|*.gif|*.png))
printf '%s\n' "${excludeResults[@]}"
Конструкція !()- це заперечна операція, щоб не включати жодне з розширень файлів, перелічених всередині та| є оператором чергування так само, як використовується в розширеній бібліотеці регулярних виразів, щоб виконати відповідність АБО глобусів.
Зауважте, що ця розширена глобальна підтримка недоступна в оболонці bourne POSIX, і вона суто специфічна для останніх версій bash. Тож якщо ви розглядаєте можливість переносимості сценаріїв, що працюють через POSIX та bashоболонки, ця опція не буде правильною.