Знайдіть каталоги, які не містять підкаталогів


10

Я пишу сценарій ksh. Потрібно знайти всі назви каталогів безпосередньо в поточній каталозі, які містять лише файли, а не підкаталоги.

Я знаю, що я міг би використовувати 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()кожного з його членів.


Схоже, це не працює, якщо каталог містить файли.
користувач394

1
Йдеться не про записи в списку каталогів, а про жорсткі посилання, що посилаються на індею каталогу. Наприклад, якщо /some/directoryмає inode # 12345678, якщо в ній немає підкаталогів, на це inode буде рівно 2 жорстких посилання: /some/directory/.і /some/directory. Він працює, чи є в каталозі файли чи ні.
telcoM

Варто зазначити, що BTRFS не є "звичайною файловою системою Unix" в цьому відношенні: на жаль, каталоги завжди мають кількість посилань 1, на жаль. (Але .і foo/..є один і той же номер індексного дескриптора.)
Peter Кордес

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команди та знайдіть ключове слово типу на цій сторінці. Ви побачите різні типи файлів, включаючи звичайні файли та каталоги тощо.

Сподіваюся, що це те, що ви шукаєте


Ні, це зовсім не питання. Це зрозуміло, як тільки ви / каталог / каталог / г. Nat Kup шукає каталоги, які не містять підкаталогів.
Жил "ТАК - перестань бути злим"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.