按日期拆分日志文件

按日期拆分日志文件

我有一个具有以下日志格式的日志文件:

###<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?

答案1

一个perl解决方案,利用 GNUdate来转换日期:

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(/^###<(.*)>/):如果行以 开头###<,则捕获<>as之间的所有内容$1(这就是括号的作用)。
  • chomp($d=date -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:我们将命令 plus的结果保存.log为变量$name
  • open(my $fh,">>","$name");$name:以文件句柄的形式打开文件$fh。如果您不知道文件句柄是什么,请不要担心,这只是意味着print $fh "foo"将打印foo$name
  • print $fh $_;:将当前行打印到文件句柄指向的文件中$fh。因此,将该行打印到当前保存为的任何文件中$name

答案2

解决此问题的一种方法是使用 awk。例如,以下命令:

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

应将文件拆分成文件,使用日期字段作为文件名

答案3

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块来保存

相关内容