Как мне объединить размеры файлов в bash, сгруппировав результаты по дате? - PullRequest
12 голосов
/ 13 марта 2009

На сервере 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-скрипт для суммирования размера файлов с разбивкой по дате, который выдает что-то вроде этого (при условии, что моя арифметика верна):

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, но я бы действительно предпочел bash-оболочку или решение awk. Мне кажется особенно сложным группировать файлы по дате в bash (особенно, если вы не можете принять определенный формат даты). Я полагаю, что суммирование размеров может быть выполнено в цикле, но есть ли более простой и элегантный подход?

Ответы [ 6 ]

15 голосов
/ 13 марта 2009

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

awk '{sum[$2]+= $1;}END{for (date in sum){print sum[date], date;}}'
8 голосов
/ 21 октября 2010

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

5 голосов
/ 12 декабря 2013

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

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
2 голосов
/ 13 марта 2009

Следуя советам 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 голос
/ 14 марта 2009

Учтите, что в 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 }
  '
0 голосов
/ 26 марта 2013

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...