Uzyskaj całkowity rozmiar pliku z pliku zawierającego listę plików

14

Mam plik zawierający listę plików, które chciałbym poznać całkowity rozmiar plików. Czy jest na to polecenie?

Mój system operacyjny jest bardzo podstawowym linuksem (Qnap TS-410).

EDYTOWAĆ:

Kilka wierszy z pliku:

/ share / archive / Bailey Test / BD006 / 0.tga
/ share / archive / Bailey / BD007 / 1 wersja 1.tga
/ share / archive / Bailey 2 / BD007 / example.tga

Nicolas
źródło
Podaj nam kilka przykładowych wierszy pliku.
EEAA
Przykład z dodanego pliku.
Nicolas,
To jakiś NAS, prawda? Czy masz zainstalowany busybox?
cjc
Tak, i myślę, że jest już zainstalowany, dlaczego?
Nicolas

Odpowiedzi:

13

Myślę, że coś takiego działałoby w busybox:

du `cat filelist.txt` | awk '{i+=$1} END {print i}'

Nie mam takiego samego środowiska jak ty, ale jeśli napotkasz problemy ze spacjami w nazwach plików, coś takiego też by działało:

cat filelist.txt | while read file;do
  du "$file"
done | awk '{i+=$1} END {print i}'

Edycja 1 :
@stew ma rację w swoim poście poniżej, du pokazuje użycie dysku, a nie dokładny rozmiar pliku. Aby zmienić zachowanie busybox używa flagi -a, więc spróbuj: du -a "$file"dla dokładnego rozmiaru pliku i porównaj dane wyjściowe / zachowanie.

Mattias Ahnberg
źródło
1
Dzięki za wkład, pierwsze polecenie powraca /usr/bin/du: Argument list too long(prawie 80 000 wierszy w moim pliku). Drugie polecenie po prostu wyświetla mi monit po naciśnięciu klawisza Enter, czekając na coś więcej?
Nicolas
Trudno powiedzieć w twoim otoczeniu. Czy to zwykły wiersz polecenia, czy tylko migający wiersz? Jeśli to drugie, może po prostu powoli czekać na wynik, jeśli jest to „monit wejściowy”, może być tak, że przegapiłeś jakąś postać? A jeśli to normalny monit, nie wiem, przetestowałem go dość dokładnie, zanim go napisałem. :(
Mattias Ahnberg,
jest to „monit wejściowy”, gdy wykonuję następujące czynności cat tgafiles.txt | while read file;do du "$file" done | awk '{i+=$1} END {print i}'. dzięki Mattias
Nicolas
1
Ach! Jeśli umieścisz wszystko w jednej linii, potrzebujesz innej; w ten sposób: cat tgafiles.txt | while read file;do du "$file";done | awk '{i+=$1} END {print i}'(tj. przed wykonaniem).
Mattias Ahnberg,
Spot on! Działa idealnie, na zdrowie! (chociaż sam mogłem sam zrozumieć ten błąd)
Nicolas
8
du -c `cat filelist.txt` | tail -1 | cut -f 1

-cdodaje wiersz „całkowity rozmiar”;
tail -1zajmuje ostatnią linię (z całkowitym rozmiarem);
cut -f 1wycina słowo „ogółem”.

olegzhermal
źródło
Nie udaje się to w przypadku zbyt długiej listy argumentów. Moja lista plików jest duża. Poniższa odpowiedź z xargs wydaje się najłatwiejszym rozwiązaniem.
Syclone0044
4

Nie wiem, czy twoje narzędzia linux są w stanie to zrobić, ale:

cat /tmp/filelist.txt  |xargs -d \\n du -c

Zrób, xargs ustawi separator jako znak nowej linii, a du wygeneruje dla ciebie wielką sumę.

Patrząc na http://busybox.net/downloads/BusyBox.html wydaje się, że „busybox du” będzie obsługiwał opcję sumy całkowitej, ale „busybox xargs” nie będzie obsługiwał niestandardowych ograniczników.

Ponownie nie jestem pewien twojego zestawu narzędzi.

cjc
źródło
oto wynik:xargs: invalid option -- d
Nicolas
Niesamowite: praca z linuxem NAS-a jest jak odcinek McGuyvera, który próbuje zbudować działający samolot z płótna, patyków i sznurka.
cjc
Co powiesz na to, jeśli masz na to miejsce na innym komputerze: skopiuj wszystkie zainteresowane pliki na inny, w pełni funkcjonalny linux, a następnie uruchom tam rozwiązanie Stew. Może to być znacznie łatwiejsze niż sprawdzenie, czy busybox jest w stanie tego dokonać.
cjc 20.01.12
1
Myślę, że odpowiedź jest najlepsza. Jest zwięzły i znacznie szybszy niż inne odpowiedzi w tym wątku.
zymhan
Dobra odpowiedź. Możesz pominąć tę -copcję, ponieważ xargs wykona wiele wywołań, dujeśli lista plików jest wystarczająco długa, generując kilka dusum.
qwr
4
while read filename ;  do stat -c '%s' $filename ; done < filelist.txt | awk '{total+=$1} END {print total}'

Jest to podobne do rozwiązania Mattiasa Ahnberga. Używanie „odczytu” pozwala ominąć problemy z nazwami plików / katalogów ze spacjami. Używam statzamiast, duaby uzyskać rozmiar pliku. du otrzymuje ilość miejsca na dysku zamiast wielkości pliku, która może być inna. W zależności od systemu plików 1 bajtowy plik będzie nadal zajmował 4k na dysku (lub jakikolwiek jest rozmiar bloku). Tak więc w przypadku pliku 1-bajtowego stat mówi 1 bajt, a du 4k.

gulasz
źródło
Dobry komentarz na temat rozmiaru pliku vs rozmiar dysku!
Mattias Ahnberg,
Naprawdę bardzo ciekawy komentarz, niestety mój linux nie zna statpolecenia:stat: command not found
Nicolas
Być może będziesz musiał powiedzieć „statystyki busyboksa”.
cjc
tak jest stat: applet not foundw tym przypadku
Nicolas
4

Oto inne rozwiązanie problemu:

cat filelist.txt | tr '\n' '\0' | wc -c --files0-from=-
dsamarin
źródło
Dla mnie (na cygwinie) du -bcdziała o wiele szybciej.
qwr
2

Wypróbuj coś takiego:

$ cat filelist.txt | xargs ls -l | awk '{x+=$5} END {print "total bytes: " x}' 

Aby poprawnie radzić sobie ze spacjami na ścieżkach:

$ find /path/to/files -type f -print0 | xargs -0 ls -l | awk '{x+=$5} END {print "total bytes: " x}' 
EEAA
źródło
dziękuję za twój wkład, niestety myślę, że jest problem z tym, że spacje w katalogach w moim pliku nie są poprzedzane znakiem „\”., dlatego psuje się podczas przeglądania listy plików.
Nicolas
Czy możesz ominąć listę plików tekstowych i po prostu wygenerować to z wyjścia find?
EEAA
niestety lista jest za długa, jest 79159 linii plików (pełna ścieżka), dlatego wysyłam ją do pliku; może mogę dodać argument o uniknięciu wyniku znalezienia?
Nicolas
nie ma argumentu „-print0” z znalezieniem w moim systemie Linux
Nicolas
@Nicolas - wynika to z użycia uproszczonego programu busybox findzamiast prawdziwego pliku findbinarnego.
EEAA
1

cat docs.txt | xargs -d \\n du -sk | awk '{total+=$1} END{print total}'

Pradeep
źródło