Ответ 1
Я часто использую эту идиому Awk:
awk '{sum[$2]+= $1;}END{for (date in sum){print sum[date], date;}}'
На сервере Linux, с которым я работаю, процесс записывает случайные имена с произвольными интервалами. Вот небольшой пример, показывающий размер файла, дату и время изменения и имя файла:
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
(Обратите внимание, что иногда размер файла может быть равен нулю.)
Что бы я хотел, это bash script, чтобы суммировать размер файлов, разбитых по дате, и выводить что-то вроде этого (при условии, что моя арифметика верна):
27679 2009-03-09
33019 2009-03-10
64527 2009-03-11
40964 2009-03-12
Результаты показывают тенденции активности с течением времени и выделяют исключительно загруженные дни.
В SQL операция будет cinch:
SELECT SUM(filesize), filedate
FROM files
GROUP BY filedate;
Теперь все это, вероятно, довольно легко в Perl или Python, но я бы предпочел bash shell или awk-решение. Мне кажется особенно сложным группировать файлы по дате в bash (особенно, если вы не можете принять определенный формат даты). Полагаю, что размеры могут быть сделаны в цикле, я полагаю, но есть ли более простой, более элегантный подход?
Я часто использую эту идиому Awk:
awk '{sum[$2]+= $1;}END{for (date in sum){print sum[date], date;}}'
(find... | xargs stat "--printf =% s +"; echo 0) | Ьс
Следуя советам ашаулей и вартека, следующий "однострочный" делает этот трюк великолепно:
ls -l --time-style=long-iso *log |
awk '{sum[$6]+= $5;}END{for (s in sum){print sum[s], s;}}' |
sort -k2 |
column -t
Только файлы, рекурсивно, отсортированные по дате и суммированные
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
Учтите, что на 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 }
'
Вот инструмент, который я создал, который позволяет выполнять SQL-подобные запросы против текстовых данных, включая группировку, объединение, условия и другие вещи. Вы можете посмотреть здесь для деталей.