Разделите файл журнала по дате

У меня есть файл журнала с этим форматом журнала:

###<Aug 8, 2016 11:59:05 PM>
different text
...
different text
###<Aug 15, 2016 9:10:55 AM>
different text
...
...
...
different text
###<Aug 22, 2016 10:02:17 PM>
different text
...
...
...
...
different text
###<Sep 1, 2016 1:00:01 AM>
different text
###<Sep 7, 2016 3:00:01 PM>
different text
...
...
different text

Как я разделяю этот файл журнала по дате в файлы YYYY_MM_DD.log?

7
задан 19 September 2016 в 14:05

3 ответа

Один подход для решения этого мог быть должен использовать awk. Например, эта команда:

awk -F'[ <,]+' '/^###/{close(f);f=$4"_"$2"_"$3".log"}{print >> f}END{close(f)}' file

должен разделить файл на файлы, с помощью полей даты в качестве имен файлов

6
ответ дан 23 November 2019 в 06:12

A perl решение, используя в своих интересах GNU date преобразовать даты:

perl -ne 'if(/^###<(.*)>/){
            chomp($d=`date -d \"$1\" +%Y_%m_%d`);
            $name="$d.log"
          } 
          open(my $fh,">>","$name"); 
          print $fh $_;' file.log 

Объяснение

  • -ne : считайте входной файл линию за линией (сохраняющий каждую строку как специальная переменная $_) и примените сценарий, данный -e к каждой строке.
  • if(/^###<(.*)>/) : если строка запускается с ###<, получите все между <> как $1 (это - то, что круглые скобки делают).
  • chomp($d=дата-d \"1$ \" + %Y _ % m _ % d); : date команда переформатировала дату. Например:

    $ date -d "Sep 1, 2016 1:00:01 AM" +%Y_%m_%d
    2016_09_01
    

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

  • $name="$d.log" : мы сохраняем результат date команда плюс .log как переменная $name.
  • open(my $fh,">>","$name"); : откройте файл $name как дескриптор файла $fh. Не волнуйтесь, не знаете ли Вы, каков дескриптор файла, это просто означает это print $fh "foo" распечатает foo в $name.
  • print $fh $_; : распечатайте текущую строку в файл что дескриптор файла $fh точки к. Так, распечатайте строку в то, что в настоящее время сохраняется как $name.
7
ответ дан 23 November 2019 в 06:12

С awk:

awk '/^#+<[^>]+>$/ {if (lines) print lines >file; \
     dt=gensub("^#+<([^>]+)>$", "\\1", $0)
     dt_cmd="date -d \""dt"\" +%Y_%m_%d.log" \
     dt_cmd | getline file; lines=$0; next}; \
     {lines=lines ORS $0} END {print lines >file}' file.log

Удобочитаемая форма:

awk '
      /^#+<[^>]+>$/ {
                    if (lines) 
                        print lines >file
                    dt=gensub("^#+<([^>]+)>$", "\\1", $0)
                    dt_cmd="date -d \""dt"\" +%Y_%m_%d.log"
                    dt_cmd | getline file; lines=$0
                    next
                    }
      {
      lines=lines ORS $0
      } 
      END {
          print lines >file
          }' file.log
  • /^#+<[^>]+>$/ соответствует строкам, содержащим даты, блок, окруженный {} будет только выполнен, если условие будет соответствовать. Если соответствия, мы получаем дату в нужном формате при помощи внешнего date команда и сохранение вывода в переменной file, и сохранение содержания переменной lines насколько файл file (от предыдущего блока), и затем инстанцируют переменной lines снова со строкой

  • Для всех других строк, мы связывающий строки как переменная lines

  • Последний блок сохраняется путем включения END блок

6
ответ дан 23 November 2019 в 06:12

Другие вопросы по тегам:

Похожие вопросы: