2009-03-13 3 views
11

На сервере Linux, с которым я работаю, процесс записывает случайные имена с произвольными интервалами. Вот небольшой пример, показывающий размер файла, дата модификации & время, и имя файла:Как суммировать размеры файлов в bash, группируя результаты по дате?

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 

(Обратите внимание, что иногда размер файла может быть равен нулю.)

Что я хотел бы это Баш скрипт просуммировать размер файлов, разбитых по дате, производя на выходе что-то вроде этого (при условии, моя арифметика верна):

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

результаты покажут тенденции активности с течением времени, и выделить исключительно напряженные дни.

В SQL, операция будет подпруга:

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

Теперь все это, вероятно, довольно легко в Perl или Python, но я действительно предпочитаю Баш оболочку или AWK решение. Мне кажется особенно сложным группировать файлы по дате в bash (особенно если вы не можете принять определенный формат даты). Полагаю, что размеры могут быть сделаны в цикле, я полагаю, но есть ли более простой, более элегантный подход?

+0

фактически можно считать, формат даты с Ls -lt --time-style = +% F – vartec

+0

Да, спасибо за это. Вместе с решением от @ashawley все собралось вместе. – yukondude

ответ

14

Я часто использую эту идиому Awk:

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

Это красиво. Я так и не понял слова, которые поддерживали awk. – yukondude

+0

Где я могу указать год? – aurelien

2

Ниже предложения от ashawley и Vartec, следующий "один вкладыш" делает трюк великолепно:

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

Считают, что на Linux вы, вероятно, GNU AWK, так что вам не нужны другие команды:

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

(найти ... | xargs stat "--printf =% s +"; echo 0) | bc

+0

Это очень хороший ответ. Кроме того, вы должны использовать 'find -print0 | xargs -0', на всякий случай (если вы не знаете, что ваши файлы все названы красиво). –

-1

Есть инструмент, который я создал, который позволяет выполнять SQL-подобные запросы против текстовых данных, включая группировку, объединение, условия и другие вещи. Вы можете посмотреть here для деталей.

2

только файлы рекурсивно сортируются по дате и суммируется

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

только файлы из текущего каталога только, отсортировано по дате и суммируется

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 
Смежные вопросы