Вас може зацікавити "бідняк find":
shopt -s globstar
shopt -s s ets названі параметри (оболонки). globstarПараметр визначається наступним чином в Баш (1) :
Якщо встановлено, шаблон, що **використовується в контексті розширення імені файла / шляху, відповідатиме файлам [sic] та нулю або більше каталогів та підкаталогів. Якщо за шаблоном слідує a /, збігаються лише каталоги та підкаталоги.
Отже, після виконання shopt -s globstarбудь-якої з наступних команд:
ls -d1 - source / ** # Символ після 'd' є цифрою.
ls -d - джерело / ** | cat # тобто запише це в трубу до будь-якої команди.
printf "% s \ n" джерело / **
дасть вихід:
source/
source/fonts
source/fonts/fontello
source/images
source/images/bg1.png
source/images/eng.png
source/images/fra.png
На жаль, сюди входять і імена каталогів. Можливо, вам це допоможе трохи знати
printf "%s\n" source/**/
дасть вихід:
source/
source/fonts
source/images
тобто лише імена каталогів. Ви можете перенаправити висновок одного з першого набору команд для одного файлу, перенаправити висновок з вище другого файлу, а потім використовувати comm, diffабо що - щось подібне, щоб відняти другий файл з перших, залишивши тільки рівнину файли (не-каталоги). Але не робіть цього.
Ще один підхід (це не набагато краще)
ls -d --file-type -- source/** | grep -v '/$'
Цей --file-typeпараметр повідомляє lsвідображати а /
в кінці кожного імені каталогу (та інших символів на кінцях інших (спеціальних) типів файлів), як це:
source // # Додано ще одне
джерело / шрифти / # Додано одне джерело
джерело / шрифти / fontello
джерело / зображення / # Додано одне
source / images / bg1.png
source / images / eng.png
source / images / fra.png
а потім grep -v '/$'видаляє лінії, які закінчуються /; тобто імена каталогів. На жаль, --file-typeопція не визначена POSIX . Якщо ваша версія lsне підтримує його, використовуйте -F. Це схоже, --file-type
за винятком того, що він також відображає *на кінцях імена виконуваних файлів, які деякі люди вважають дратує. Їх можна усунути за допомогою sed:
ls -dF -- source/** | sed -e '/\/$/d' -e 's/\*$//'
Якщо ви хочете зробити щось із усіма файлами (і лише з файлами), ви можете зробити це
для f в джерелі / **
робити
якщо [-f "$ f"]
потім
Вставте команди, які слід застосувати до звичайних файлів.
фі
зроблено
Примітки:
- Коли
lsвиводиться на термінал, і він не перебуває в -l( l ong) режимі, він записує кілька імен на рядок (якщо тільки імена не дуже довгі). Ви можете змусити його писати одне ім’я на рядок, вказавши -1(одне) або перенаправляючи вихід у файл чи трубу.
- Напевно, вам не потрібні команди
--в lsкомандах, оскільки ви перераховуєте каталог, вміст якого ви створили. Ви повинні використовувати його при переліку *в невідомому каталозі як захист від імен файлів, які починаються з цього -.
- Не намагайтеся проаналізувати вихід з
ls.
globstarВаріант оболонки , здається , не визначається POSIX. (Насправді я не впевнений, що POSIX розпізнає будь-які параметри оболонки.) Хоча це, мабуть, є bashism, будьте обережні - він може бути присутнім не у всіх версіях bash.
Якщо є fontsабо imagesє підкаталоги, **перерахуйте їх усі, рекурсивно, аж донизу. Один (дещо химерний і ненадійний) спосіб обмеження глибини - це
ls -d --file-type -- source/** | grep -v '\(/.*\)\{3\}'
який видаляє рядки, що містять три або більше /символів.
findнеправильного використання ; особливо, якщо ви біжитеfor file in $(find ...), ви вдарили по одному з них).