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 ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.