Вас может заинтересовать « find бедняка»:
shopt -s globstar
shopt -s s етсь названный вариант оболочки (s).
Опция globstar определяется в bash (1) следующим образом:
Если установлено, шаблон ** используемый в контексте расширения имени файла / пути, будет соответствовать файлам [sic] и нулю или более каталогов и подкаталогов.
Если за шаблоном следует символ / , совпадают только каталоги и подкаталоги.
Итак, после того, как вы сделали shopt -s globstar , выполните любую из следующих команд:
ls -d1 -- source/** # The character after the ‘d’ is the digit one.
ls -d -- source/** | cat # i.e., it will write that into a pipe to any command.
printf "%s\n" source/**
будет производить вывод:
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// # Added an extra one
source/fonts/ # Added one
source/fonts/fontello
source/images/ # Added one
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/\*$//'
Если вы хотите что-то сделать со всеми файлами (и только файлами), вы можете сделать
for f in source/**
do
if [ -f "$f" ]
then
Insert commands to be applied to plain files here.
fi
done
Заметки:
- Когда
ls выводит на терминал, и он не находится в режиме -l (l ong), он записывает несколько имен в строке (если имена не очень длинные).
Вы можете заставить его написать по одному имени в строке, указав -1 (один) или перенаправив вывод в файл или канал.
- Вам, вероятно, не нужны команды
-- в ls поскольку вы указываете каталог, содержимое которого вы создали.
Вы должны использовать его при перечислении * в неизвестном каталоге, как защита от имен файлов, начинающихся с - .
- Не пытайтесь анализировать вывод из
ls .
- Параметр оболочки
globstar видимому, не определяется POSIX. (На самом деле, я не уверен, что POSIX распознает какие-либо параметры оболочки.)
Хотя это кажется bash ism, будьте осторожны - он может присутствовать не во всех версиях bash.
Если у fonts или images есть подкаталоги, ** перечислит их все, рекурсивно, до конца.
Один (несколько грязный и ненадежный) способ ограничения глубины
ls -d --file-type -- source/** | grep -v '\(/.*\)\{3\}'
который удаляет строки , содержащие три или более / символов.