Найти каталоги, которые не содержат подкаталогов

10

Я пишу сценарий кш. Необходимо найти все имена каталогов непосредственно в текущем каталоге, которые содержат только файлы, а не подкаталоги.

Я знаю, что мог бы использовать ls -alRи рекурсивно анализировать выходные данные для первой буквы в первом поле ( dдля каталога). Я думаю, что awkэто лучший способ разобрать и найти.

Например, простой ls -alвывод в текущем каталоге:

   drwxr-xr-x  22 af      staff    748 18 Mar 22:21 .
   drwxr-xr-x   5 root    admin    170 17 Mar 18:03 ..
   -rw-------   1 af      staff      3 17 Mar 16:37 .CFUserTextEncoding
   drwxr-xr-x   5 af      staff    170 17 Mar 17:12 Public
   drwxr-xr-x   9 af      staff    306 18 Mar 17:40 Sites
   -rw-------   1 af      staff      3 17 Mar 16:37 textd
   

В этом выводе 2 каталога: Publicи Sites. Каталог Publicне содержит подкаталогов, но содержит Sites. Есть 3 подкаталога в Sites. Поэтому мне нужно отображать только те каталоги, в которых нет каталогов. В моем случае это только Sites.

Нат Куп
источник

Ответы:

1

Вам не нужно использовать awkвообще. Используйте встроенные тесты, которые kshобеспечивают что-то вроде этого:

#!/bin/ksh

for NAME in *
do
    FOUND=no
    if [[ -d $NAME && $NAME != '.' && $NAME != '..' ]]
    then
        for SUBNAME in $NAME/*
        do
            if [[ -d $SUBNAME ]]
            then
                FOUND=yes
                break
            fi
        done
        if [[ $FOUND == no ]]
        then
            echo Found only files in $NAME
        fi
    fi
done

Этот маленький скрипт просматривает все каталоги в текущем каталоге и сообщает вам, содержат ли они только файлы, а не подкаталоги.

Брюс Эдигер
источник
14

Если вы можете использовать findи работаете в «нормальной файловой системе Unix» (то есть как определено в find (1) в описании параметра -noleaf ), то можно использовать следующую команду:

find . -type d -links 2

Каждый каталог имеет как минимум 2 имени (жестких ссылки): .и его имя. Его подкаталоги, если таковые имеются, будут иметь ..указание на родительский каталог, поэтому каталог с N подкаталогами будет иметь количество жестких ссылок, равное N + 2. Таким образом, ища каталоги с количеством жестких ссылок, равным 2, мы ищем каталоги с N = 0 подкаталогами.

Так что, если вы можете использовать find, это, пожалуй, самый быстрый метод и, очевидно, превосходит циклы внутри оболочки над содержимым каталога, stat()содержащим каждого из его членов.

intelfx
источник
Это не работает, если каталог содержит какие-либо файлы.
user394
1
Речь идет не о записях в списке каталогов, а о жестких ссылках, ссылающихся на индекс узла. Например, если у /some/directoryнего есть индекс # 12345678, если у него нет подкаталогов, будет ровно 2 жестких ссылки на этот индекс: /some/directory/.и /some/directory. Это работает, есть ли какие-либо файлы в каталоге.
Телеком
В этом отношении стоит упомянуть, что BTRFS не является «нормальной файловой системой Unix»: к сожалению, каталоги всегда имеют количество ссылок, равное 1. (Но .и foo/..есть один и тот же номер инода.)
Питер Кордес
3

*/соответствует подкаталогам текущего каталога. Это включает в себя символические ссылки на каталоги, которые вы можете или не можете желать.

В ksh93 добавление ~(N)в начале шаблона приводит к его расширению до пустого списка, если совпадений нет. Без этого шаблон остается неизменным, если нет соответствия.

Следующая функция ksh93 выводит список подкаталогов текущих каталогов, которые не содержат ни одного подкаталога или ссылки на каталог.

list_leaf_directories () {
  local FIGNORE='.?(.)'        # don't ignore dot files
  local d
  for d in */; do
    [[ -L $d ]] || continue;   # skip symbolic links
    set -- ~(N)"$d"/*/
    if ((!$#)); then echo "$d"; fi
  done
done
Жиль "ТАК - перестань быть злым"
источник
0

если я вас не правильно понял, вам нужно только найти файлы в каталоге, а не в подкаталогах. Если это ваше намерение, вот решение

find . -type f

если вы хотите найти не обычные файлы (например, файлы блочных устройств, файлы символьных устройств и т. д.), обратитесь к справочной странице по findкоманде и найдите ключевое слово type на этой странице. Вы увидите различные типы файлов, в том числе обычные файлы и каталоги и т. Д.

Надеюсь, это то, что вы ищете

MelBurslan
источник
Нет, это совсем не вопрос. Это достаточно понятно, как только вы перешли в каталог / catalog / directory / g. Nat Kup ищет каталоги, которые не содержат подкаталогов.
Жиль "ТАК - перестань быть злым"