2009-03-13 8 views
11

Auf einem Linux-Server, mit dem ich arbeite, schreibt ein Prozess zufällig benannte Dateien in zufälligen Intervallen. Hier ist eine kleine Probe, welche die Dateigröße, Änderungsdatum & Zeit und Dateiname:Wie summiere ich Dateigrößen in bash zusammen und gruppiere die Ergebnisse nach Datum?

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 

(Beachten Sie, dass manchmal die Dateigröße Null sein kann.)

Was würde Ich mag ein Bash-Skript die Größe der Dateien summieren, nach Datum aufgeschlüsselt, Ausgabe in etwa so produzieren (vorausgesetzt, meine Arithmetik korrekt ist):

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

die Ergebnisse Aktivität Trends im Laufe der Zeit würden zeigen, und die außergewöhnlich arbeitsreiche Tage markieren.

In SQL, würde der Betrieb zum Kinderspiel sein:

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

Nun, dies alles wahrscheinlich in Perl oder Python ist ziemlich einfach, aber ich würde wirklich ein Bash-Shell oder awk Lösung bevorzugen. Es scheint mir besonders schwierig zu sein, die Dateien nach Datum in bash zu gruppieren (besonders, wenn Sie kein bestimmtes Datumsformat annehmen können). Die Größe zu summieren könnte man in einer Schleife machen, nehme ich an, aber gibt es einen leichteren, eleganteren Ansatz?

+0

tatsächlich können Sie das Datumsformat mit ls annehmen -lt --time-style = +% F – vartec

+0

Ja, danke dafür. Zusammen mit der Lösung von @ashawley kommt alles zusammen. – yukondude

Antwort

14

benutze ich oft dieses Idiom von Awk:

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

Das ist schön. Ich habe awk-unterstützte Wörterbücher nicht so einfach realisiert. – yukondude

+0

Wo kann ich das Jahr angeben? – aurelien

2

die Vorschläge von ashawley und vartec Folgen, die folgende "one-liner" ist der Trick hervorragend:

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

Bedenken Sie, dass auf Linux Sie wahrscheinlich GNU awk haben, so brauchen Sie keine anderen Befehle:

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

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

+0

Das ist eine sehr gute Antwort. Außerdem sollten Sie 'find -print0 | verwenden xargs -0', nur für den Fall (es sei denn, Sie wissen, dass Ihre Dateien alle schön benannt sind). –

-1

Dort ein Tool, das ich erstellt habe, die SQL-ähnliche Abfragen für Textdaten ermöglicht, einschließlich Gruppierung, Joins, Bedingungen und andere Sachen. Sie können einen Blick auf here für Details werfen.

2

Nur Dateien, rekursiv, sortiert nach Datum und summierten

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

werden nur die Dateien, aus aktuellen Verzeichnis nur, sortiert nach Datum und summierten

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 
Verwandte Themen