Odpowiedzi:
Szukasz potoków ( |). Są sposobem łączenia wielu poleceń i przekazywania danych wyjściowych jednego polecenia jako danych wejściowych do drugiego. W takim przypadku chcesz przekazać wszystkie nazwy plików, które znajdziesz jako dane wejściowe du(które obliczają rozmiar). Ponieważ jednak duoczekuje , że nazwy plików, a wyniki findsą tylko listą tekstu (tak, tekst składa się z nazw plików, ale dunie wie, że wszystko, co widzi, to tekst), musisz użyć czegoś takiego, xargsktóry weźmie każdy wiersz tekstu, potraktuj go jak nazwę pliku i przekaż go do du. Łącząc to wszystko, otrzymujemy:
find . -name "*.o" | xargs du -sch
zawsze powinieneś cytować wzory, które podajesz find(tak jak ja powyżej "*.o":). Jeśli nie, powłoka rozwinie *.onazwy wszystkich pasujących plików w bieżącym katalogu. W tym przypadku działało tylko dlatego, że nie masz pasujących plików.
Te -schflagi dla dudokumentowane są w man du:
-c, --total
produce a grand total
-h, --human-readable
print sizes in human readable format (e.g., 1K 234M 2G)
-s, --summarize
display only a total for each argument
Należy jednak pamiętać, że to się nie powiedzie w przypadku nazw plików zawierających białe znaki. Prawie na pewno nie będzie to problemem dla plików obiektowych, ale w przyszłości, jeśli będziesz musiał również zajmować się spacjami, użyj:
find . -name "*.o" -print0 | xargs -0 du -sch
Te -print0marki findwydrukować NULL rozdzielone linie i -0marki xargspodjęcia takich linii jak wejścia.
Alternatywnie możesz findwydrukować same rozmiary, a następnie zsumować je:
find . -name "*.o" -printf '%s\n' | awk '{c+=$1}END{print c}'
Obejdzie to również problem wspomniany przez @Serg w komentarzach, w których jest zbyt wiele argumentów, a polecenie jest podzielone na osobne polecenia.
Jeśli używasz bash(prawdopodobnie używasz), istnieje prostszy sposób:
shopt -s globstar
du -sch **/*.o
Te shopt globstarmarki dowodzenia **pasują do wszystkich plików i podkatalogów lub więcej. Po włączeniu **/*.odopasuje wszystkie pliki (i katalogi), których nazwa kończy się na .o, więc możemy przekazać to bezpośrednio do du.
Zauważ, że w przeciwieństwie do tego findpodejścia, nie będzie to pasowało do ukrytych plików (tych, których nazwa zaczyna się na a .). Aby je również dopasować, wykonaj:
shopt -s dotglob globstar
du -sch **/*.o
shopt globstarprzykład pomija -s; Musiałem użyć shopt -s globstarpodobnego do twojego drugiego przykładu.
shopt OPTIONbez -slub lub -u(lub innej opcji, zobacz help shopt) po prostu drukuje bieżącą wartość OPCJI. Musisz shopt -s OPTIONje włączyć i shopt -u OPTIONwyłączyć.
Użyj -exec flagi, aby uruchomić dupolecenie z ;(co oznacza dla każdego pliku)
find . -name "*.o" -exec du -b {} \; | awk '{total+=$1}END{print total}'
Przykładowe dane wyjściowe:
$ find . -name "*.txt" -exec du -b {} \; | awk '{total+=$1}END{print total,"bytes" }'
find: ‘./.cache/gvfs-burn’: Permission denied
find: ‘./.cache/unity’: Permission denied
852690242 bytes
findjest rekurencyjny - co oznacza, że przechodzi przez wszystkie podkatalogi. Jeśli chcesz tylko uzyskać wszystkie *.opliki w bieżącym katalogu, po prostu zrób
du -b -c *.o
z perlem:
perl -le 'map { $sum += -s } @ARGV; print $sum' -- *.pdf
Rozmiar wszystkich nie ukrytych plików PDF w bieżącym katalogu.
.oplików i mogą znajdować się w podkatalogach. Możesz także dodać }{wcześniej, print $sumaby uniknąć drukowania sumy dla każdej iteracji. Chcemy tylko ostatniego.
dui powstanie wieletotallinii. Oto przykład: paste.ubuntu.com/23092752