基于日期标记/时间戳分割文本文件

时间:2015-12-17 00:10:48

标签: bash debian

我有包含日期​​标记的大日志文件。它看起来像这样:

[01/11/2015, 02:19]
foo
[01/11/2015, 08:40]
bar
[04/11/2015, 12:21]
foo
bar
[08/11/2015, 14:12]
bar
foo
[09/11/2015, 11:25]
...
[15/11/2015, 19:22]
...
[15/11/2015, 21:55]
...

等等。我需要将这些数据拆分成几天的文件,例如:

01.txt:

[01/11/2015, 02:19]
foo
[01/11/2015, 08:40]
bar

04.txt:

[04/11/2015, 12:21]
foo
bar

等。我怎样才能使用任何unix工具呢?

3 个答案:

答案 0 :(得分:4)

我不认为有一个工具可以在没有一点编程的情况下完成它,但是使用Awk,小编程确实不是那么难。

script.awk

/^\[[0-3][0-9]\/[01][0-9]\/[12][0-9]{3},/ {
    if ($1 != old_date)
    {
        if (outfile != "") close(outfile);
        outfile = sprintf("%.2d.txt", ++filenum); 
        old_date = $1
    }
}
{ print > outfile }

第一个(更大的)代码块识别日期字符串,该字符串也在$1中(因此,通过引用$1可以使条件更精确,但它对非最小的好处-existent)。在操作中,它会检查日期是否与其记住的最后日期不同。如果是,则检查是否打开了文件并在必要时将其关闭(close是POSIX awk的一部分)。然后它会生成一个新文件名,并记住它正在处理的当前日期。

第二个较小的块只是将当前行写入当前文件。

调用

awk -f script.awk data

这假设您有一个文件script.awk;如果您愿意,可以将其作为脚本参数提供。如果整个封装在shell脚本中,我会使用表达式而不是第二个文件,但我觉得开发使用文件很方便。 (shell脚本将包含awk '…the script…' "$@",没有单独的文件。)

示例输出文件

根据问题的样本数据,输出有五个文件,01.txt .. 05.txt

$ for file in 0?.txt; do boxecho $file; cat $file; done
************
** 01.txt **
************
[01/11/2015, 02:19]
foo
[01/11/2015, 08:40]
bar
************
** 02.txt **
************
[04/11/2015, 12:21]
foo
bar
************
** 03.txt **
************
[08/11/2015, 14:12]
bar
foo
************
** 04.txt **
************
[09/11/2015, 11:25]
...
************
** 05.txt **
************
[15/11/2015, 19:22]
...
[15/11/2015, 21:55]
...
$

boxecho命令是一个简单的脚本,它在一组星星中回应它的参数:

echo "** $* **" | sed -e h -e s/./*/g -e p -e x -e p -e x

修订文件名格式

  

我希望根据文件中的日期输出[day].txt[day].[month].[year].txt。这可能吗?

是;这是可能的,而不是特别困难。 split函数是处理$1中的值的一种方法。正则表达式指定方括号,斜杠和逗号是字段分隔符。 $1中的值中有5个子字段:[之前的空字段,由斜杠分隔的三个数字组件和,之后的空字段。数组名称dmy是存储组件的序列的助记符。

/^\[[0-3][0-9]\/[01][0-9]\/[12][0-9]{3},/ {
    if ($1 != old_date)
    {
        if (outfile != "") close(outfile)
        n = split($1, dmy, "[/\[,]")
        outfile = sprintf("%s.%s.%s.txt", dmy[4], dmy[3], dmy[2])
        old_date = $1
    }
}
{ print > outfile }

置换sprintf()语句中的数字4,3,2以适合自己。给定的订单是年,月,日,它有许多优点,包括它正在利用ISO 8601标准,文件自动排序到日期顺序。我强烈建议使用它,但你可以按照自己的意愿行事。对于示例数据和问题中显示的输入,它生成的文件是:

2015.11.01.txt
2015.11.04.txt
2015.11.08.txt
2015.11.09.txt
2015.11.15.txt

答案 1 :(得分:0)

这是我的想法。我使用sed命令和awk脚本。

$ cat biglog
[01/11/2015, 02:19]
foo
[01/11/2015, 08:40]
bar
[04/11/2015, 12:21]
foo
bar
aaa
bbb
[08/11/2015, 14:12]
bar
foo

$ cat sample.awk
#!/bin/awk -f

BEGIN {
  FS = "\n"
  RS = "\n\n"
}

{
  date = substr($1, 2, 2)
  filename = date ".txt"

  for (i = 2; i <= NF; i++) {
    print $i >> filename
  }
}

如何使用

sed -e 's/^\(\[[0-9][0-9]\)/\n\1/' biglog | sed -e 1d | ./sample.awk

<强>确认

ls *.txt
01.txt  04.txt  08.txt

$ cat 01.txt
foo
bar

$ cat 04.txt
foo
bar
aaa
bbb

$ cat 08.txt
bar
foo

答案 2 :(得分:0)

另一个awk

$ awk -F"[[/,]" -v d="." '/^[\[0-9\/, :\]]*$/{f=$4 d $3 d $2 d"txt"} 
                                        {print $0>f}' file

$ ls 20*
2015.11.01.txt  2015.11.04.txt  2015.11.08.txt  2015.11.09.txt  2015.11.15.txt

$ cat 2015.11.01.txt 
[01/11/2015, 02:19]
foo
[01/11/2015, 08:40]
bar