Wypisywanie rozmiarów katalogów pod konsolą
Czasem zdarza się ze zastanawiamy się co zajmuje tyle miejsca w danym katalogu, najlepszym sposobem na sprawdzenie tego jest wpisanie po prostu ls -lh, co wypisze nam wszystkie pliki w danym katalogu i poda ich rozmiary w przystępnej formie(kilobajty, megabajty etc.), jednak problem pojawi się kiedy mamy w tym katalogu jakieś podkatalogi, otrzymamy wtedy tylko rozmiar każdego z tych katalogów bez ich zawartości(zwykle będą to 4KB), a przecież nie o to nam chodziło. Przedstawię więc kilka sposobów jak otrzymać rozmiary wszystkiego w danym katalogu, bez wyjątku:)
- du -h --max-depth=1, lub poprostu du -sh * oto najprostsze i zarazem najlepsze rozwiązanie tego problemu, wielkie dzięki dla skolima za wspomnienie mi o tym, poniższe rowiązania są wiec bardziej ciekawostką.
- du -sh $(ls -A) najpierw za pomocą ls wypisujemy listę plików z danego katalogu, parametr -A sprawia że wypisywane są też pliki których nazwa zaczyna się od . czyli pliki ukryte(z wyjątkiem . i ..), kiedy już mamy listę plików przekazujemy ją do polecenia du, które zwróci rozmiar każdego z tych plików, a więc również podkatalogów(jak wiemy w linux'ie wszystko jest plikiem), parametr -s sprawia będziemy otrzymywali łączny rozmiar każdego katalogu, bez rozdrabniania się na katalogi, co uczyni wszystko czytelniejszym, natomiast -h sprawia ze rozmiary będą wypisywane w przystępnych dla ludzi jednostkach(czyli jak wcześniej: kilobajtach, megabajtach, gigabajtach itd.). Sposób ten nie jest jednak pozbawiony wad, gdyż jeśli mamy w naszym katalogu pliki ze spacjami w nazwach zamiast wyświetlać ich rozmiary będzie zgłaszał błędy. Poniżej przedstawię więc lepsze rozwiązanie.
- shopt -s dotglob; for x in *; do du -sh "$x"; done oto rozwiązanie lepsze od powyższego, bo mamy pewność ze na pewno uwzględni wszystkie pliki i nie pominie tych ze spacjami czy innymi dziwnymi znakami w nazwach. Jest w prawdzie sporo dłuższe, ale czemu nie zrobić aliasu bądź nie zapisać do do pliku i wrzucić do /usr/bin. Już omawiam co się tam dzieje: shopt -s dotglob zmienia ustawienia aktualnej powłoki sprawiając że przy listowaniu wszystkich plików za pomocą gwiazdki będą także pokazywane pliki ukryte. Dalej mamy pętle która wykonuje dla każdego pliku w danym katalogu znane nam już polecenie du -sh, a przed dziwnymi znakami w nazwach zabezpieczyliśmy się ujmując zmienną $x zawierającą nazwy kolejnych plików w "".
Tylko katalogi:)
Czasem zwykłe pliki nas nie interesują i chcemy wylistować tylko rozmiary katalogów, oto jak to zrobic:
- du -h --max-depth=1 */ zmiana w tym poleceniu to zastąpienie * przez */, co zamiast wszystkich plików w danym katalogu wybiera tylko katalogi się w nim znajdujące.
- shopt -s dotglob; for x in */; do du -sh "$x"; done róznica między wersją dla wszystkich plików, a tą jest taka sama jak w powyższym przypadku.
- find -maxdepth 1 -type d -exec du -sh '{}' ';' to rozwiązanie trwa ponad 2 krotnie dłużej niż sposób z wykorzystaniem pętli(pętla: 1m 3.916s, find: 2m 31.236s). Tak w skrócie omówię to polecenie: -maxdepth 1 sprawia że find nie będzie zagłębiał się w podkatalogi, -type d wybiera tylko pliki które są katalogami, -exec wykonuje jakieś polecenie dla każdego z plików, w naszym przypadku, znane nam już du -sh.
Na zakończenie jeszcze skrypcik autorstwa DeeTah, który wyświetla pliki jak ls, ale podaje poprawne rozmiary katalogów:
for PLICZEK in *; do
ROZMIAR=$( ls -dlh "$PLICZEK" | awk '{ print $5 }' )
FAKTYCZNY_ROZMIAR=$(du --si --summarize "$PLICZEK" | awk '{print $1 }' )
ls -dlh "$PLICZEK" | sed "s@$ROZMIAR@$FAKTYCZNY_ROZMIAR@g"
done
Dodatkowe informacje:
- man find
- man bash
- man du
- man ls
04 września 2008 o 17:47:44
> to rozwiązanie daje głównie jaki ciekawostkę
Tak, zawsze najpoprawniejsze rozwiązanie daje się jako ciekawostkę. Spróbuj sobie mieć trochę więcej katalogów w bieżącym katalogu.
04 września 2008 o 17:49:48
Znowu trolujesz? Artykul pisałem wyknując wszystkier polecenia na moim home, wiec było bardzo dużo plików.
04 września 2008 o 18:12:31
du -h --max-depth=1
Po co kombinować?
04 września 2008 o 18:18:46
A moim zdaniem najwięcej sensu miałoby zrobienie ls -lh i podmienienie piątej kolumny efektem pracy du:
for PLICZEK in *; do
ROZMIAR=$( ls -dlh "$PLICZEK" | awk '{ print $5 }' )
FAKTYCZNY_ROZMIAR=$(du --si --summarize "$PLICZEK" | awk '{print $1 }' )
ls -dlh "$PLICZEK" | sed "s@$ROZMIAR@$FAKTYCZNY_ROZMIAR@g"
done
04 września 2008 o 18:27:25
@skolima: Przejrzałem cały manual od du a to przeoczyłem-dzieki;)
@DeeTah : moge dodac to do artykułu?
04 września 2008 o 18:41:14
Jeśli uważasz, że ma taką wartość, to jasne ;)
06 września 2008 o 15:21:55
@DeeTah: Niestety kolumny nie są równo wyświetlane ale skrypcik ciekawy. Awka nie umiem dlatego moje pytanie, da się tam powstawiać coś w stylu: '\x1b[10G' dla każdej kolumny z osobna?