Znajdź katalogi, które nie zawierają podkatalogów

10

Piszę skrypt to ksh. Musisz znaleźć wszystkie nazwy katalogów bezpośrednio w bieżącym katalogu, które zawierają tylko pliki, a nie podkatalogi.

Wiem, że mogłem użyć ls -alRi rekursywnie przeanalizować dane wyjściowe dla pierwszej litery w pierwszym polu ( ddla katalogu). Myślę, że awkto najlepszy sposób na parsowanie i znajdowanie.

Na przykład proste ls -alwyjście w bieżącym katalogu:

   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
   

Dane wyjściowe zawierają 2 katalogi: Publici Sites. Katalog Publicnie zawiera podkatalogów, ale Siteszawiera. Istnieją 3 podkatalogi w Sites. Muszę więc powtórzyć tylko te katalogi, które nie zawierają w sobie katalogów. W moim przypadku jest to tylko Sites.

Nat Kup
źródło

Odpowiedzi:

1

W ogóle nie musisz używać awk. Skorzystaj z wbudowanych testów, które kshzapewniają:

#!/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

Ten mały skrypt sprawdza wszystkie katalogi w bieżącym katalogu i informuje, czy zawierają one tylko pliki, a nie podkatalogi.

Bruce Ediger
źródło
14

Jeśli jesteś w stanie używać findi pracujesz na „normalnym systemie plików Uniksa” (to znaczy, jak zdefiniowano w find (1) w opisie opcji -noleaf ), możesz użyć następującego polecenia:

find . -type d -links 2

Każdy katalog ma co najmniej 2 nazwy (twarde linki): .i jego nazwę. Jego podkatalogi, jeśli istnieją, będą ..wskazywały na katalog nadrzędny, więc katalog z N podkatalogów będzie miał twardą liczbę linków równą N + 2. Tak więc, szukając katalogów z liczbą twardych linków równą 2, szukamy katalogów z podkatalogami N = 0.

Tak więc, jeśli możesz użyć find, jest to prawdopodobnie najszybsza metoda i oczywiście lepsza niż pętle w powłoce nad zawartością katalogu stat()obejmującą każdego z jej członków.

intelfx
źródło
Nie działa to, jeśli katalog zawiera jakieś pliki.
user394
1
Nie chodzi o wpisy na liście katalogów, ale o twarde linki odnoszące się do i-węzła katalogu. Na przykład, jeśli /some/directoryma i-węzeł # 12345678, jeśli nie ma podkatalogów, będą dokładnie 2 twarde linki do tej i-węzły: /some/directory/.i /some/directory. Działa niezależnie od tego, czy w katalogu znajdują się jakieś pliki.
telcoM
Warto wspomnieć, że BTRFS nie jest pod tym względem „normalnym systemem plików Uniksa”: niestety katalogi zawsze mają liczbę linków równą 1. (Ale .i foo/..mają ten sam numer i-węzła).
Peter Cordes
3

*/pasuje do podkatalogów bieżącego katalogu. Obejmuje to symboliczne linki do katalogów, których możesz chcieć lub nie.

W ksh93 dodanie ~(N)na początku wzoru powoduje rozwinięcie go do pustej listy, jeśli nie ma dopasowania. Bez tego wzorzec pozostaje niezmieniony, jeśli nie ma dopasowania.

Poniższa funkcja ksh93 wyświetla podkatalogi bieżących katalogów, które nie zawierają żadnego podkatalogu ani łącza do katalogu.

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
Gilles „SO- przestań być zły”
źródło
0

jeśli cię nie rozumiem, chcesz tylko znaleźć pliki w katalogu, a nie w podkatalogach. Jeśli taki jest twój zamiar, oto rozwiązanie

find . -type f

jeśli chcesz znaleźć inne niż zwykłe pliki (takie jak pliki urządzeń blokowych, pliki urządzeń znakowych itp.), przejdź do strony man dla findpolecenia i poszukaj słowa kluczowego type na tej stronie. Zobaczysz różne typy plików, w tym zwykłe pliki i katalogi itp.

Mam nadzieję, że tego właśnie szukasz

MelBurslan
źródło
Nie, to wcale nie jest pytanie. Jest to całkiem jasne, gdy s / catalog / directory / g. Nat Kup szuka katalogów, które nie zawierają podkatalogów.
Gilles „SO- przestań być zły”