liczenie liczby katalogów w określonym katalogu

103

Jak policzyć liczbę folderów w określonym katalogu. Używam następującego polecenia, ale zawsze zapewnia ono dodatkowe.

find /directory/ -maxdepth 1 -type d -print| wc -l

Na przykład, jeśli mam 3 foldery, to polecenie zapewnia 4. Jeśli zawiera 5 folderów, polecenie zapewnia 6. Dlaczego?

user2566898
źródło
4
Dodatkowa liczba 1 występuje z powodu bieżącego katalogu „.” , co jest również uwzględniane przez „znajdź”.
patel deven

Odpowiedzi:

94

find drukuje również sam katalog:

$ find .vim/ -maxdepth 1 -type d
.vim/
.vim/indent
.vim/colors
.vim/doc
.vim/after
.vim/autoload
.vim/compiler
.vim/plugin
.vim/syntax
.vim/ftplugin
.vim/bundle
.vim/ftdetect

Zamiast tego możesz przetestować dzieci katalogu i w ogóle do nich nie wchodzić:

$ find .vim/* -maxdepth 0 -type d
.vim/after
.vim/autoload
.vim/bundle
.vim/colors
.vim/compiler
.vim/doc
.vim/ftdetect
.vim/ftplugin
.vim/indent
.vim/plugin
.vim/syntax

$ find .vim/* -maxdepth 0 -type d | wc -l
11
$ find .vim/ -maxdepth 1 -type d | wc -l
12

Możesz również użyć ls:

$ ls -l .vim | grep -c ^d
11


$ ls -l .vim
total 52
drwxrwxr-x  3 anossovp anossovp 4096 Aug 29  2012 after
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 autoload
drwxrwxr-x 13 anossovp anossovp 4096 Aug 29  2012 bundle
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 colors
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 compiler
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 doc
-rw-rw-r--  1 anossovp anossovp   48 Aug 29  2012 filetype.vim
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftdetect
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftplugin
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 indent
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 plugin
-rw-rw-r--  1 anossovp anossovp 2505 Aug 29  2012 README.rst
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 syntax

$ ls -l .vim | grep ^d
drwxrwxr-x  3 anossovp anossovp 4096 Aug 29  2012 after
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 autoload
drwxrwxr-x 13 anossovp anossovp 4096 Aug 29  2012 bundle
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 colors
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 compiler
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 doc
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftdetect
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftplugin
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 indent
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 plugin
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 syntax
Pavel Anossov
źródło
Miły! Jak byś to zrobił $ ls -l .vimz PHP? Albo jak uzyskać tylko sumę, bez listy. Mam na myśli, że w tym przypadku tylko 52?
Pathros
Hah. Uwielbiam to, że argumentem przeciwko PowerShell jest to, że BASH jest łatwiejszy pod każdym względem ... chcesz zobaczyć polecenie POSH, aby to zrobić? (ls).Count
Kolob Canyon
@Pathros Użyj globu z flagą GLOB_ONLYDIR i policz () wynik.
Pilipe,
1
ls -l | grep -c ^djest śmiertelnie prosta i działa. @Pathros jest prawdopodobnie lepszy sposób w PHP, ale w najgorszym przypadku w PHP zawsze możesz użyć funkcji shell_exec () do wykonania wiersza poleceń i zwrócenia wyników do łańcucha. ie $dirCount = shell_exec('ls -l | grep -c ^d');
gigabyte
66

Uzyskaj liczbę tylko katalogów w bieżącym katalogu

echo */ | wc

wyjdziesz jak 1 309 4594

2nd digitoznacza nie. katalogów.

lub

tree -L 1 | tail -1

EmptyData
źródło
8
Nie udaje się to, jeśli w nazwach katalogów są niestety spacje.
Michael Campbell,
zsh: no matches found: */need nullglob
Anne van Rossum
@AnnevanRossum Czy masz echo. typwhich echo
EmptyData
7
Pierwszą można nieco ulepszyć:echo */ | wc -w
ibic
Zwróć uwagę, że będzie to liczyć 1, jeśli nie ma katalogów zamiast 0.
jinawee
27
find . -mindepth 1 -maxdepth 1 -type d | wc -l

Do znaleziska -mindepthoznacza Łączna recusive w katalogach

-maxdepth oznacza całkowitą liczbę recusive w katalogach

-type d oznacza katalog

A dla wc -lśrodków policz linie wejścia

shiyani suresh
źródło
2
Czy możesz wyjaśnić swoją odpowiedź (wewnątrz odpowiedzi)?
Zulu
-mindepth oznacza całkowitą liczbę recusive w katalogach, -maxdepth oznacza całkowitą liczbę recusive w katalogach, -type d oznacza katalog, a wc -l oznacza liczbę linii z podanego katalogu
shiyani suresh
find . -mindepth 1 -maxdepth 1 -type d | wc -lda ci dużo spacji między liczbą, na przykład: ` dir_count=`find . -maxdepth 1 -type d | wc -l | xargs`; echo $dir_count # will print just 2 if (( $dir_count > 1 )); then echo "Yaa"; fi # will print "Yaa"
2`
16

Jeśli masz tylko katalogi w folderze i nie masz plików, to robi to:

ls | wc -l
Brainmaniac
źródło
2
Pobiera to również pliki, ale pytanie dotyczyło folderów / katalogów.
Robert
12

Najlepszy sposób, aby przejść do dysku i po prostu wykonać

ls -lR | grep ^d | wc -l

i znaleźć wszystkie foldery łącznie, w tym podkatalogi?

find /mount/point -type d | wc -l

... lub znaleźć wszystkie foldery w katalogu głównym (bez podkatalogów)?

find /mount/point -maxdepth 1 -type d | wc -l

Twoje zdrowie!

Manish Shrivastava
źródło
Zauważ, że poprzednie ls -lRignorują katalog z prefiksem kropkowym podczas ich find -type d liczenia, więc liczba podana przez pierwsze polecenie jest błędna, jeśli masz katalogi z prefiksem kropkowym (na przykład masz podkatalog .git!). Nie możesz po prostu użyć, -lRaponieważ otrzymujesz również dla każdego katalogu .i ..wpisu. Dotyczy to również odpowiedzi @Pavel Anossov
marcz
12

Uruchom stat -c %h folderi odejmij 2 od wyniku. Wykorzystuje to tylko jeden podproces w przeciwieństwie do 2 (lub nawet 3) wymaganych przez większość innych rozwiązań tutaj (zazwyczaj findplus wc).

Korzystanie z sh / bash:

cnt = $ ((`stat -c% h folder` - 2))
echo $ cnt # 'echo' to wbudowane sh / bash, a nie dodatkowy proces

Korzystanie z csh / tcsh:

@ cnt = `stat -c% h folder` - 2
echo $ cnt # 'echo' to wbudowane csh / tcsh, a nie dodatkowy proces


Objaśnienie: stat -c %h folderwyświetla liczbę twardych dowiązań do folderu , a każdy podfolder w folderze zawiera wpis ../, który jest twardym łączem z powrotem do folderu . Musisz odjąć 2, ponieważ licznik zawiera dwa dodatkowe twarde dowiązania:

  1. własny, odwołujący się do siebie wpis ./ folderu i
  2. Folder „s rodzica Link do folderu
textral
źródło
Związane z tym pytaniem: [Dlaczego nowy katalog ma twardą liczbę łączy równą 2, zanim cokolwiek zostanie do niego dodane? ] ( unix.stackexchange.com/questions/101515 ) Wyjaśnia, dlaczego jest to doskonała odpowiedź. Niestety nie poświęcono temu wystarczającej uwagi! Chociaż jest to dobra odpowiedź, jej wynik zależy niestety od systemu plików, ale w przypadku większości popularnych systemów plików to zadziała.
kvantour
8

Myślę, że najłatwiej jest

  ls -ld images/* | wc -l

gdzie imagesjest twój katalog docelowy. Flaga -d ogranicza do katalogów, a opcja -l wykonuje listowanie w każdym wierszu, zgodne z bardzo dobrze znaną w wc -lprzypadku liczby wierszy.

briceburg
źródło
Zwraca również wynik +1
josef
1
Według man ls, -drobi: „lista same katalogi, a nie ich zawartość”, czyli po uruchomieniu ls /tmp, dostaniesz co jest /tmp, a jeśli uruchomić ls -d /tmppo prostu dostać /tmp. -dPrzełącznik nie filtruje katalogów, jak został poproszony o.
Robert
5

Kilka przydatnych przykładów:

count plików w aktualnym katalogu

/bin/ls -lA  | egrep -c '^-'

count dirs w aktualnym reż

/bin/ls -lA  | egrep -c '^d'

liczyć pliki i katalogi w aktualnym reż

/bin/ls -lA  | egrep -c '^-|^d'

policzyć pliki i katalogi w jednym podkatalogu

/bin/ls -lA  subdir_name/ | egrep -c '^-|^d'

Zauważyłem dziwną rzecz (przynajmniej w moim przypadku):

Kiedy próbowałem lszamiast /bin/ls tego -Aparametr do not list implied . and ..NIE DZIAŁA, zgodnie z oczekiwaniami. Kiedy używam lstego programu ./ i ../ Więc wynik jest zły. ROZWIĄZANIE: /bin/lszamiast tegols

MTK
źródło
4

Nr katalogu, który możemy znaleźć za pomocą poniższego polecenia

ls -l | grep "^d" | wc -l

user1388547
źródło
Po prostu ls -l | grep ^d | wc -lzrobię, nie ma potrzeby "tutaj używać
kaspiotr
3

Czyste rozwiązanie bash:

shopt -s nullglob
dirs=( /path/to/directory/*/ )
echo "There are ${#dirs[@]} (non-hidden) directories"

Jeśli chcesz również policzyć ukryte katalogi:

shopt -s nullglob dotglob
dirs=( /path/to/directory/*/ )
echo "There are ${#dirs[@]} directories (including hidden ones)"

Zauważ, że będzie to również liczyło linki do katalogów. Jeśli tego nie chcesz, ta metoda jest nieco trudniejsza.


Używając find:

find /path/to/directory -type d \! -name . -prune -exec printf x \; | wc -c

Sztuczka polega na tym, xaby za każdym razem, gdy katalog został znaleziony, wypisać na standardowe wyjście, a następnie użyć go wcdo zliczenia liczby znaków. Policzy to liczbę wszystkich katalogów (w tym ukrytych), z wyłączeniem linków.


Przedstawione tutaj metody są bezpieczne dla zabawnych znaków, które mogą pojawić się w nazwach plików (spacje, znaki nowej linii, znaki globu itp.).

gniourf_gniourf
źródło
To najlepsze rozwiązanie przedstawione w tym pytaniu i będzie działać zawsze!
kvantour
3

Używając zsh:

a=(*(/N)); echo ${#a}

NJest nullglob, /sprawia, że pasuje do katalogów, #liczniki. Zgrabnie poradzi sobie ze spacjami w nazwach katalogów, a także zwraca, 0jeśli nie ma katalogów.

Anne van Rossum
źródło
0

Policz wszystkie pliki i podfoldery, styl systemu Windows:

dir=/YOUR/PATH;f=$(find $dir -type f | wc -l); d=$(find $dir -mindepth 1 -type d | wc -l); echo "$f Files, $d Folders"
margenn
źródło
0

Jeśli chcesz używać wyrażeń regularnych, spróbuj:

ls -c | grep "^d" | wc -l
makassi
źródło
1
Czy chcesz dodać wyjaśnienie do odpowiedzi zawierającej tylko kod? Pomogłoby to w walce z błędnym przekonaniem, że StackOverflow to bezpłatna usługa pisania kodu. Zajrzyj także tutaj, aby poprawić wygląd: stackoverflow.com/editing-help
Yunnosch
0

Najlepsza odpowiedź na to, czego chcesz, to

echo `find . -maxdepth 1 -type d | wc -l`-1 | bc

to odejmuje jeden, aby usunąć niechciane „.” katalog, który znajduje listy (jak wspomniano powyżej patel deven).

Jeśli chcesz liczyć podfoldery rekurencyjnie, po prostu zostaw opcję maxdepth, więc

echo `find . -type d | wc -l`-1 | bc

PS Jeśli podstawianie poleceń jest brzydkie, odejmowanie jednego można wykonać jako czysty strumień za pomocą sedi bc.

Odejmowanie jednego od liczby:

find . -maxdepth 1 -type d | wc -l | sed 's/$/-1\n/' | bc

lub dodając count do minus jeden:

find . -maxdepth 1 -type d | wc -l | sed 's/^/-1+/' | bc
Dr Osoba Osoba II
źródło
-1

Najlepszy sposób na to:

ls -la | grep -v total | wc -l

To daje idealną liczbę.

Manoj
źródło
6
Masz na myśli, że to najgorszy sposób! poza tym nie liczy to liczby katalogów. A co, jeśli istnieje nazwa katalogu zawierająca ciąg total? twoja metoda jest zepsuta :(. Nie analizujls !
gniourf_gniourf