LINUX.ORG.RU

Каталоги-листья


0

0
Есть развесистое дерево каталогов разной глубины. Нужно вывести (желательно, при помощи обычного find) все каталоги-листья - т.е. каталоги, у которых нет ни одного дочернего каталога, только родительский каталог. Не может быть, чтоб я был первым, кому это понадобилось... mindepth/maxdepth пляшут от базового каталога, а при переменной глубине дерева это бесполезно.

ЗЫ В воспаленный мозг на ночь глядя приходят кошмарные мысли об использовании find ... -exec с вложенным find - но это как-то совсем уж злобно...

★★★★★
> дерево

tree? :-)

tree -d <root directory>

anonymous
()
Предложу такую бяку (может оказаться полупропеченым, но должно быть
близко к тому, что надо)

-----------------

#!/bin/bash

godown(){
dirs=$(ls -R | grep ./)
if [ -z "$dirs" ]
then echo "$(pwd) is a leaf"
fi
for thing in *
do 
if [ -d "$thing" ] 
then
cd "$thing"; godown
fi
done
cd ..
}

godown

-----------------
Uncle_Theodore ★★
()
что-то типа того должно помочь:
find . -depth -type d выведет сначала все листья, а потом директории, их содержащие. по этому списку надо пройтись авком, сверяя текущую строку с dirname от предыдущей. это исключит те самые директории, которые содержат листья.
BreadFan ★★
()
Ответ на: комментарий от BreadFan
Интересная мысль. Подумаю.

А вообще, видать, не зря я задал вопрос - почему-то мне сначала казалась задача тривиальной, а оказалась, тупого решения как-то нет...

svu ★★★★★
() автор топика
Есть вот такая идея с рекурсивным find:

find -type d -exec find '{}' -mindepth 1 -type d -printf "#" -quit \; -print | grep -v '^#'

Davidov ★★★★
()
Ответ на: комментарий от Davidov
Что-то в этом духе я и имел в виду. Спасибо за доведение до осмысленного.
svu ★★★★★
() автор топика
Ответ на: комментарий от Davidov
спасибо за идею. немного громоздкая, конечно.
у меня правда условие - наличие определенного файла(ов) в данной директории.
давно искал решение...
пока остановился на этом:
find -type d -exec find "{}" -maxdepth 1 -iname MASK -printf "#" -quit \; -print | grep "^#./" | sed -e "s/^#.\///"

теперь надо бы от этого дела получить basename
только вот вопрос: как?
передавать -print0 через grep хорошо ли?
может есть возможность сделать как-то еще?
xydo ★★
()
Ответ на: комментарий от xydo
>теперь надо бы от этого дела получить basename
хм. всё несколько проще:
вместо  sed -e "s/^#.\///"
sed -e "s/.*\///"
xydo ★★
()
> ЗЫ В воспаленный мозг на ночь глядя приходят кошмарные мысли об использовании find ... -exec с вложенным find - но это как-то совсем уж злобно...

Моск надо беречь. Можно просто сделать листнг директорий и обработать его любимым напильником. Если, конечно же, нужен именно список директорий, а не реализация фп с хвостовой рекурсией на баше. )))

LamerOk ★★★★★
()
Ответ на: комментарий от svu
Вызывают сомнения: 
dirs=$(ls -R | grep ./) 

Это не имеет значения, это просто проверка, что в директории нет
поддиректорий. Пусто -- оно и в Африке пусто, и с пробелами пусто.:)

... 
for thing in * 

А это да. Лучше for thing in "*"
Еще имеет смысл все одним ифом сделать, а не двумя. Будет короче.
Uncle_Theodore ★★
()
Ответ на: комментарий от Uncle_Theodore
> Лучше for thing in "*"

Ой. Тогда thing будет ВСЕМ СПИСКОМ. Одна итерация цикла. Как-то не то, чего хочется.

svu ★★★★★
() автор топика
Ответ на: комментарий от svu
тогда можно попробовать с использованием двух скриптов
в одном:
find ... -exec sh 2.sh '{}'

во втором:
if [...]
then
echo "$1"
fi

можно и вообще всё в 1 скрипт запихнуть, но прийдется делать дополнительный параметр
xydo ★★
()
Ответ на: комментарий от xydo
Да я просто идею Davidov довел до ума. Спасибо ему.
svu ★★★★★
() автор топика
Ответ на: комментарий от ero-sennin
Ну-у.... так не интересно....
svu ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.