Вас може зацікавити "бідняк 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 розпізнає будь-які параметри оболонки.) Хоча це, мабуть, є bash
ism, будьте обережні - він може бути присутнім не у всіх версіях bash.
Якщо є fonts
або images
є підкаталоги, **
перерахуйте їх усі, рекурсивно, аж донизу. Один (дещо химерний і ненадійний) спосіб обмеження глибини - це
ls -d --file-type -- source/** | grep -v '\(/.*\)\{3\}'
який видаляє рядки, що містять три або більше /
символів.
find
неправильного використання ; особливо, якщо ви біжитеfor file in $(find ...)
, ви вдарили по одному з них).