Mały wpis ku pamięci: jak policzyć, ile miejsca zajmują w danym drzewie katalogów pliki z wybranymi rozszerzeniami.
W moim przypadku chciałem się dowiedzieć, ile miejsca zajmują filmy rodzinne. Pierwszym krokiem będzie odszukanie wszystkich filmów:
Zamiast używać standardowej konstrukcji -name
użyłem wyrażenia regularnego. Pozwoliło ona na dużo bardziej zwarte umieszczenie wszystkich rozszerzeń, które mnie interesują.
Teraz wypada wyświetlić informację, ile miejsca zajmuje każdy z plików. Można to tego użyć opcji -exec
w połączeniu z wywołaniem polecenia ls
, ale dużo lepszy efekt da użycie przełącznika -ls
. Efekt będzie podobny, a całość będzie funkcjonować dużo szybciej.
Ostatnim elementem będzie wyciągnięcie kolumny z wielkością pliku i jej zsumowanie, można to zrobić przy użyciu polecenia awk
:
I to w sumie rozwiązuje problem.
Ja jeszcze tylko chciałem mieć wielkość plików wyświetlaną w megabajtach. Można sobie do przeliczyć używając nawet zwykłego polecenia echo
, chociaż spada drastycznie czytelność kodu i tworzy się taki potworek:
#1 by jahoo on 2012/05/15 - 09:17
nie wystarczy: du -ch `find ….` ?
Łukasz Stelmach Reply:
Maj 16th, 2012 at 01:00
Hmm, ciekawe, nie pomyślałem od du ani przez chwilę 😉
Natomiast, w mojej sytuacji mam kilka problemów:
1. Dużą ilość plików – przekracza dopuszczalną ilość danych, jakie można przekazać do polecenia w linii poleceń.
2. Pliki zawierają w nazwach znak spacji, który przeszkadza w prostym ich wykorzystaniu.
I efekt użycia samego du -ch trochę różni się od tego co proponowałem (ale to akurat jest najmniejszy problem).
Ze znakiem spacji w nazwie można sobie poradzić, czy też poprzez definicję zmiennej $IFS w bashu, lub chyba lepiej poprzez użycie odpowiednich przełączników w poleceniu find -print0 oraz du –null. Niestety, jakoś nie chciało mi to ze sobą zagrać.
Problem 1 jest już bardziej skomplikowany i tutaj trzeba podejść do sprawy inaczej. Na szczęście polecenie du udostępnia przełącznik –files0-from, pozwala przesłać listę plików do sprawdzenia rozdzielonych znakiem NULL.
W każdym razie, ja skończyłem na takiej formie polecenie:
find . -iregex „.*\.\(mp4\|mpeg\|avi\|3gp\|mov\|webm\)” -print0 | du -chs –files0-from=- | tail -n 1
I to robi praktycznie to samo co polecenie z awk, a na pewno jest prostsze.