Jak policzyć rekurencyjnie wszystkie pliki w katalogach

47

Chcę zobaczyć, ile plików znajduje się w podkatalogach, aby dowiedzieć się, gdzie jest całe użycie i-węzła w systemie. Jakbym zrobił to dla wykorzystania przestrzeni

du -sh /*

co da mi miejsce używane w katalogach poza katalogiem głównym, ale w tym przypadku chcę liczbę plików, a nie ich rozmiar.

ksenoterracid
źródło
Zobacz także rekurencyjne zliczanie wszystkich plików w katalogu , liczyć pliki w każdym katalogu? w SU.
Gilles „SO- przestań być zły”
Myślę, że „ile plików znajduje się w podkatalogach w tamtych podkatalogach” jest mylącą konstrukcją. Jeśli wyraźniej określisz, czego chcesz, możesz uzyskać odpowiedź, która pasuje do rachunku.
Steven D
@ Steven może go przepisać ... Pomyślałem, że mój przykład du -sh /*wyjaśnił, jak chciałem, żeby hrabia działał. to samo, po prostu policz pliki, a nie bajty.
Xenoterracide
Jak wspomniałeś o użyciu i-węzła, nie rozumiem, czy chcesz policzyć liczbę plików, czy liczbę używanych i-węzłów. Oba są różne, gdy w systemie plików występują twarde łącza. Większość, jeśli nie wszystkie, odpowiedzi podają liczbę plików. Nie używaj ich na dysku kopii zapasowej Apple Time Machine.
mouviciel
@mouviciel nie jest to używane na dysku z kopią zapasową i tak, przypuszczam, że mogą być inne, ale w środowisku, w którym jestem, jest bardzo niewiele linków, technicznie po prostu muszę to wyczuć. dowiedzieć się, gdzie ktoś wypala tam limit i-węzłów.
Xenoterracide

Odpowiedzi:

60
find -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done

Podziękowania dla Gilles i ksenoterrakidu za poprawki dotyczące bezpieczeństwa / zgodności.

Pierwsza część: find -maxdepth 1 -type dzwróci listę wszystkich katalogów w bieżącym katalogu roboczym. To jest przesyłane do ...

Druga część: while read -r dir; dorozpoczyna pętlę while - tak długo, jak długo potok wchodzący do while jest otwarty (czyli do momentu wysłania całej listy katalogów), polecenie odczytu umieści następny wiersz w zmiennej „dir”. Następnie kontynuuje ...

Trzecia część: printf "%s:\t" "$dir";wypisze ciąg znaków w „$ dir” (który zawiera jedną z nazw katalogów), a następnie tabulator.

Czwarta część: find "$dir -f file"tworzy listę wszystkich plików w nazwie katalogu przechowywanych w „$ dir”. Ta lista jest wysyłana do ..

Piąta część: wc -l;zlicza liczbę wierszy wysłanych na standardowe wejście.

Ostatnia część: donepo prostu kończy pętlę while.

Otrzymujemy więc listę wszystkich katalogów w bieżącym katalogu. Dla każdego z tych katalogów generujemy listę wszystkich plików w nim, abyśmy mogli je wszystkie policzyć wc -l. Wynik będzie wyglądał następująco:

./dir1: 234
./dir2: 11
./dir3: 2199
...
Shawn J. Goff
źródło
Zawsze używaj read -rjako zwykłych readtrików specjalnie dla ukośników. Wtedy echo -en "$dir:\t"znów zacznie mangować ukośniki odwrotne; printf '%s:\t' "$dir"zamiast tego należy użyć prostej poprawki . Następnie $dirpowinno być "$dir"( zawsze używaj podwójnych cudzysłowów wokół podstawień zmiennych ).
Gilles „SO- przestań być zły”
zmodyfikowano zgodnie z sugestiami @Gilesfind -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" | wc -l; done
ksenoterracyd
2
Dodaję sort -n -r -k2do końca to, dla wielu katalogów, tak, że wiem, gdzie jest najbardziej Wykorzystanie
xenoterracide
Czwarta część: znajdź „$ dir” tworzy listę wszystkich plików w nazwie katalogu przechowywanych w „$ dir”. Zapomniałeś dodać, -type faby zrobić listę plików:find -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done
Krzysztof Boduch,
@ krzysiek-boduch Dzięki! Zaktualizowałem odpowiedź.
Shawn J. Goff,
15

Spróbuj find . -type f | wc -l, policzy wszystkie pliki w bieżącym katalogu, a także wszystkie pliki w podkatalogach. Pamiętaj, że wszystkie katalogi nie będą liczone jako pliki, tylko zwykłe pliki.

herohuyongtao
źródło
13

Oto kompilacja kilku przydatnych poleceń list (ponownie zakodowanych na podstawie kodu poprzednich użytkowników):

Lista folderów z liczbą plików:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type f | wc -l); printf "%4d : %s\n" $n "$dir"; done

Lista folderów z niezerową liczbą plików:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type f | wc -l); if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Lista folderów z liczbą podfolderów:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type d | wc -l); let n--; printf "%4d : %s\n" $n "$dir"; done

Lista folderów z niezerową liczbą podfolderów:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type d | wc -l); let n--; if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Wyświetl puste foldery:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" | wc -l); let n--; if [ $n -eq 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Wyświetl niepuste foldery z liczbą treści:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" | wc -l); let n--; if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done
DolphinDream
źródło
I btw .. jeśli chcesz, aby dane wyjściowe któregokolwiek z tych poleceń listy były posortowane według liczby pozycji .. potokuj polecenie w sortowanie: "a-list-command" | sort -n
DolphinDream
12

Próbować:

find /path/to/start/at -type f -print | wc -l

jako punkt początkowy lub jeśli naprawdę chcesz rekursować tylko przez podkatalogi katalogu (i pomiń pliki w tym katalogu najwyższego poziomu)

find `find /path/to/start/at -mindepth 1 -maxdepth 1 -type d -print` -type f -print | wc -l
Cry Havok
źródło
+1 za coś | wc -l ... liczba słów to takie miłe małe narzędzie
Johan
tak, ale robi to tylko 1 katalog .... Chciałbym uzyskać liczbę wszystkich katalogów w katalogu i nie chcę uruchamiać go osobno za każdym razem ... oczywiście przypuszczam, że mógłbym użyć pętli ... ale jestem leniwy.
Xenoterracide
finddomyślnie działa rekurencyjnie we wszystkich podkatalogach. Jeśli chcesz, aby działał w wielu lokalizacjach, możesz określić wszystkie między findi -type.
Didier Trosset
ten drugi z pewnością nie działa ... Próbowałem go na / home. Mam 698035 . Powinienem zobaczyć około 6 liczb.
Xenoterracide
To działa dla mnie - czy na pewno masz tylko 6 plików /home? Byłbym w 100% pewien, że nie.
Cry Havok,
4

Poniższe rozwiązanie liczy rzeczywistą liczbę używanych i-węzłów, zaczynając od bieżącego katalogu:

find . -print0 | xargs -0 -n 1 ls -id | cut -d' ' -f1 | sort -u | wc -l

Aby uzyskać liczbę plików tego samego podzbioru, użyj:

find . | wc -l

W przypadku rozwiązań eksplorujących tylko podkatalogi, bez uwzględnienia plików w bieżącym katalogu, możesz odnieść się do innych odpowiedzi.

mouviciel
źródło
1
Dobry pomysł, biorąc pod uwagę twarde linki. Zakładając GNU find, nie trzeba tak wiele czynności: find -printf '%i\n' | sort -u | wc -l. Jeśli chcesz być przenośny, potrzebujesz find . -exec ls -id {} + | cut …zamiast tego.
Gilles „SO- przestań być zły”
2

OS X 10.6 dusi polecenie w zaakceptowanej odpowiedzi, ponieważ nie określa ścieżki dla find. Zamiast tego użyj:

find . -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done
abeboparebop
źródło
2

Wiem, że jestem spóźniony na imprezę, ale wierzę, że to czyste bash(lub inna powłoka, która akceptuje podwójną gwiazdę globu) może być znacznie szybsze w niektórych sytuacjach:

shopt -s globstar    # to enable ** glob in bash
for dir in */; do a=( "$dir"/**/* ); printf "%s\t%s\n" "$dir:" "${#a[*]}"; done

wynik:

d1/:    302
d2/:    24
d3/:    640
...
jimmij
źródło
1

Wypróbuj to:

find -type d -print0 | xargs -0 -I {} sh -c 'printf "%s\t%s\n" "$(find "{}" -maxdepth 1 -type f | wc -l)" "{}"'

Powinno działać dobrze, chyba że nazwy plików zawierają znaki nowej linii.

Dennis Williamson
źródło
zbyt rekurencyjne ... Chcę tylko zobaczyć najwyższy poziom, na którym sumuje się wszystko pod nim. w sumie ... to kończy drukowanie każdego katalogu.
Xenoterracide
@xenoterracide: Spróbuj dodać -maxdepth 1natychmiast po pierwszym find. Jeśli chcesz uwzględnić liczbę podkatalogów w swoim liczniku, usuń je -type fna końcu (i tak powinno być naprawdę ! -type d, aby wszystkie pliki inne niż katalogi zostały uwzględnione).
Dennis Williamson
1

Jeśli masz ncduzainstalowany (niezbędny, gdy chcesz zrobić porządki), po prostu wpisz c„Przełącz wyświetlanie liczby elementów podrzędnych”. I C„Sortuj według przedmiotów”.

Demi-Lune
źródło
1
lol, to musi być najczęściej akceptowana odpowiedź :)
x-yuri
0

du --inodes

Nie jestem pewien, dlaczego nikt (w tym ja) nie był świadomy:

du --inodes
--inodes
      list inode usage information instead of block usage

Jestem prawie pewien, że to rozwiązuje problem PO. Zacząłem z niego często korzystać, aby dowiedzieć się, gdzie są wszystkie śmieci na moich ogromnych dyskach (i przenieść je na starszy dysk).

Dalsze informacje

Jeśli nie chcesz się powtarzać (co może być przydatne w innych sytuacjach), dodaj

-S, --separate-dirs
Sridhar Sarnobat
źródło