it-swarm-eu.dev

Vyhledejte celkovou velikost určitých souborů v rámci adresáře

Předpokládejme, že existuje adresář pro ukládání obrázků, řekněme: ./photos/john_doe, ve kterém je více podadresářů, kde je umístěno mnoho určitých souborů (řekněme: *.jpg). Jak mohu vypočítat souhrnnou velikost těchto souborů pod john_doe větev?

Zkusil jsem du -hs ./photos/john_doe/*/*.jpg, ale zobrazí se pouze jednotlivé soubory. Také se sleduje pouze první úroveň vnoření john_doe adresář, například john_doe/june/, ale přeskočí john_doe/june/outrageous/.

Jak tedy mohu projít celou větev a shrnout velikost určitých souborů?

162
mbaitoff
find ./photos/john_doe -type f -name '*.jpg' -exec du -ch {} + | grep total$

Pokud je vyžadováno více než jedno vyvolání du, protože seznam souborů je velmi dlouhý, bude hlášeno více součtů a je třeba je sečíst.

210
SHW
du -ch public_html/images/*.jpg | grep total
20M total

dává mi úplné využití mého .jpgsložky v tomto adresáři.

Chcete-li pracovat s více adresáři, pravděpodobně byste to museli zkombinovat s find nějak.

Možná vám bude příklady příkazů d užitečné (zahrnuje také find)

55
Levon

Především potřebujete dvě věci:

  • -c možnost du, řekněte jí, aby vytvořil celkový součet;
  • buď ** ( pokyny k aktivaci ) nebo find ( příklad ) nebo k procházení podadresářů.
du -ch -- **/*.jpg | tail -n 1

Konečná odpověď zní:

{ find <DIR> -type f -name "*.<EXT>" -printf "%s+"; echo 0; } | bc

a ještě rychlejší verze, neomezená RAM, ale to vyžaduje GNU AWK s podporou bignum):

find <DIR> -type f -name "*.<EXT>" -printf "%s\n" | gawk -M '{t+=$1}END{print t}'

Tato verze má následující funkce:

  • všechny možnosti find k určení souborů, které hledáte
  • podporuje miliony souborů
    • ostatní odpovědi jsou omezeny maximální délkou seznamu argumentů
  • vytváří pouze 3 jednoduché procesy s minimální propustností potrubí
    • mnoho odpovědí zde vytváří procesy C + N, kde C je nějaká konstanta a N je počet souborů
  • neobtěžuje se manipulací s řetězci
    • tato verze nedělá žádné grepping nebo regexing
    • no, find provádí jednoduché zástupné porovnávání názvů souborů
  • volitelně naformátuje částku do podoby, kterou lze přečíst člověkem (např. 5.5K, 176.7M, ...)
    • k tomu připojit | numfmt --to=si
19
rindeal

Odpovědi, které byly dosud poskytnuty, neberou v úvahu, že seznam souborů předávaný z find to du může být tak dlouhý, že find automaticky rozdělí seznam do bloků, což má za následek mnohonásobný výskyt total.

Můžeš buď grep total (locale!) a sčítejte ručně, nebo použijte jiný příkaz. AFAIK existují pouze dva způsoby, jak získat celkový součet (v kilobajtech) všech souborů nalezených pomocí find:
find . -type f -iname '*.jpg' -print0 | xargs -r0 du -a| awk '{sum+=$1} END {print sum}'

Vysvětlení
find . -type f -iname '*.jpg' -print0: Vyhledejte všechny soubory s příponou jpg bez ohledu na velikost písmen (tj. * .Jpg, * .JPG, * .Jpg ...) a vydejte je (ukončeno nulovou hodnotou).
xargs -r0 du -a: -r: Xargs by příkaz zavolal i bez předání argumentů, což zabrání -r. -0 znamená null zakončené řetězce (nikoli zakončení nového řádku).
awk '{sum+=$1} END {print sum}': Sčítá výstup velikosti souboru pomocí předchozího příkazu

A pro orientaci by tomu bylo jinak
find . -type f -iname '*.jpg' -print0 | du -c --files0-from=-

10
Jan

Pokud je seznam souborů příliš velký, že jej nelze předat na jediné vyvolání du -c, v systému GNU) můžete:

find . -iname '*.jpg' -type f -printf '%b\t%D:%i\n' |
  sort -u | cut -f1 | paste -sd+ - | bc

(velikost vyjádřená počtem 512 bytových bloků). Stejně jako du se snaží počítat pevné odkazy pouze jednou. Pokud vám nezáleží na pevných odkazech, můžete je zjednodušit:

(printf 0; find . -iname '*.jpg' -type f -printf +%b) | bc

Pokud chcete místo využití disku velikost, nahraďte %b s %s. Velikost bude potom vyjádřena v bajtech.

4

Dosud zmiňovaná řešení jsou neefektivní (spuštění je drahé) a vyžaduje součet dalších manuálních prací, pokud je seznam souborů dlouhý nebo nefungují v systému Mac OS X. Následující řešení je velmi rychlé, mělo by fungovat na jakémkoli systému a dává celkovou odpověď v GB (odebrat a/1024, pokud chcete vidět součet v MB): find . -iname "*.jpg" -ls |Perl -lane '$t += $F[6]; print $t/1024/1024/1024 . " GB"'

2
hobbydad

du přirozeně prochází hierarchii adresářů a awk může provádět filtrování, takže něco takového může stačit:

du -ak | awk 'BEGIN {sum=0} /\.jpg$/ {sum+=$1} END {print sum}'

Funguje to bez GNU.

2
GeoffP

Vylepšuje skvělou odpověď SHW, aby fungovala s jakýmkoli národním prostředím, jak Zbyszek již ve své poznámce zdůraznil:

LC_ALL=C find ./photos/john_doe -type f -name '*.jpg' -exec du -ch {} + | grep total$
2
lbo

Další by bylo

ls -al <directory> | awk '{t+=$5}END{print t}}'

Za předpokladu, že hledáte v jednom adresáři. Pokud se chcete podívat na aktuální adresář a pod ním

ls -Ral <directory> | awk '{t+=$5}END{print t}}'
0
chris bird

To pro mě fungovalo.

find -type f -iname *.jpg -print0 | du -ch --files0-from=- | grep total$
0
serendrewpity

Jiná alternativa používat stat spíše než du

stat -L -c %s ** | awk '{s+=$1} END {printf "%.0f\n", s}'

Viz Gillesova odpověď na používání **

0
Peter Frost