2009-03-13 11 views
11

Na serwerze Linux, z którym pracuję, proces zapisuje losowo wybrane pliki w losowych odstępach czasu. Oto mała próbka, pokazując rozmiar pliku, data modyfikacji & czas, a nazwa pliku:Jak sumować rozmiary plików w bashach, grupując wyniki według daty?

27659 2009-03-09 17:24 APP14452.log 
0  2009-03-09 17:24 vim14436.log 
20  2009-03-09 17:24 jgU14406.log 
15078 2009-03-10 08:06 ySh14450.log 
20  2009-03-10 08:06 VhJ14404.log 
9044 2009-03-10 15:14 EqQ14296.log 
8877 2009-03-10 19:38 Ugp14294.log 
8898 2009-03-11 18:21 yzJ14292.log 
55629 2009-03-11 18:30 ZjX14448.log 
20  2009-03-11 18:31 GwI14402.log 
25955 2009-03-12 19:19 lRx14290.log 
14989 2009-03-12 19:25 oFw14446.log 
20  2009-03-12 19:28 clg14400.log 

(Należy pamiętać, że czasami rozmiar pliku może wynosić zero.)

Chciałbym to skrypt bash Podsumowując wielkość plików, w podziale według daty, produkujących wyjściowe coś jak to (zakładając, że moja arytmetyka jest poprawna):

27679 2009-03-09 
33019 2009-03-10 
64527 2009-03-11 
40964 2009-03-12 

wyniki wykaże tendencje aktywności w czasie, i podkreślają wyjątkowo zajęty dzień.

W SQL, operacja byłaby Cinch:

SELECT SUM(filesize), filedate 
FROM files 
GROUP BY filedate; 

Teraz to wszystko prawdopodobnie całkiem łatwa w Perl lub Python, ale tak naprawdę wolą powłoki bash lub roztwór awk. Szczególnie trudne wydaje mi się pogrupowanie plików według daty w bashu (szczególnie, jeśli nie można przyjąć określonego formatu daty). Podsumowując, rozmiary mogłyby być wykonane w pętli, jak sądzę, ale czy istnieje łatwiejsze, bardziej eleganckie podejście?

+0

rzeczywiście można założyć, format daty ls -lt --time-style = +% F – vartec

+0

Tak, dzięki za to. Wraz z rozwiązaniem z @ashawley, to wszystko się razem. – yukondude

Odpowiedz

14

często używam tego idiomu awk:

awk '{sum[$2]+= $1;}END{for (date in sum){print sum[date], date;}}' 
+0

To jest piękne. Nie zdawałem sobie sprawy, że słowniki wspierane przez awk są po prostu tak proste. – yukondude

+0

Gdzie mogę podać rok? – aurelien

2

następstwie sugestii ashawley i vartec następujący "one-liner" ma trick znakomicie:

ls -l --time-style=long-iso *log | 
    awk '{sum[$6]+= $5;}END{for (s in sum){print sum[s], s;}}' | 
    sort -k2 | 
    column -t 
1

Uważają, że na Linuksie prawdopodobnie masz GNU awk, więc nie trzeba innych poleceń:

ls -l --time-style=long-iso * | 
    WHINY_USERS=-9 awk 'END { 
    for (s in sum) 
     printf "%-15s\t%s\n", sum[s], s 
     } 
    { sum[$6]+= $5 } 
    ' 
7

(znajdź ... | xargs stat "--printf =% s +"; echo 0) | bc

+0

To jest bardzo dobra odpowiedź. Powinieneś także użyć 'find -print0 | xargs -0', na wszelki wypadek (chyba że wiesz, że wszystkie pliki są ładnie nazwane). –

-1

Utworzone przeze mnie narzędzie umożliwia wykonywanie kwerend podobnych do zapytania SQL dotyczących danych tekstowych, w tym grupowania, łączenia, warunków i innych rzeczy. Szczegółowe informacje można znaleźć na stronie here.

2

tylko pliki, rekursywnie, sortowane według daty i sumowane

find ./ -type f -printf '%TY-%Tm-%Td %s\n'|awk '{sum[$1]+= $2;}END{for (date in sum){print date, sum[date];}}'|sort 

tylko pliki z bieżącego katalogu tylko, sortowane według daty i sumowane

find ./ -maxdepth 1 -type f -printf '%TY-%Tm-%Td %s\n'|awk '{sum[$1]+= $2;}END{for (date in sum){print date, sum[date];}}'|sort 
Powiązane problemy