我有包含日期标签的大日志文件。它看起来像这样:
[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]
...
Run Code Online (Sandbox Code Playgroud)
等等。我需要将这些数据分成几天的文件,例如:
01.txt:
[01/11/2015, 02:19]
foo
[01/11/2015, 08:40]
bar
Run Code Online (Sandbox Code Playgroud)
04.txt:
[04/11/2015, 12:21]
foo
bar
Run Code Online (Sandbox Code Playgroud)
等我如何使用任何 unix 工具来做到这一点?
我不认为有一个工具可以在没有一点编程的情况下完成它,但是有了 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 }
Run Code Online (Sandbox Code Playgroud)
第一个(较大的)代码块识别日期字符串,它也在$1(因此可以通过引用使条件更精确$1,但它的好处最小甚至不存在)。在动作内部,它会检查日期是否与它记住的最后一个日期不同。如果是这样,它会检查它是否有打开的文件并在必要时关闭它(close是 POSIX 的一部分awk)。然后它生成一个新文件名,并记住它正在处理的当前日期。
第二个较小的块只是将当前行写入当前文件。
awk -f script.awk data
Run Code Online (Sandbox Code Playgroud)
这假设您有一个文件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]
...
$
Run Code Online (Sandbox Code Playgroud)
该boxecho命令是一个简单的脚本,它在一个星星框中回显其参数:
echo "** $* **" | sed -e h -e s/./*/g -e p -e x -e p -e x
Run Code Online (Sandbox Code Playgroud)
我希望根据文件中的日期输出为 a
[day].txt或[day].[month].[year].txt。那可能吗?
是的; 这是可能的,并不是特别难。该split函数是处理分解 中值的一种方法$1。正则表达式指定方括号、斜线和逗号是字段分隔符。中的值有 5 个子字段$1:在 之前的空字段[、由斜杠分隔的三个数字组件和在 之后的空字段,。数组名称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 }
Run Code Online (Sandbox Code Playgroud)
排列语句中的数字 4、3、2sprintf()以适合您自己。给定的顺序是年、月、日,它有很多优点,包括它利用了 ISO 8601 标准,并且文件会自动按日期顺序排序。我强烈建议使用它,但您可以随心所欲。对于问题中显示的示例数据和输入,它生成的文件是:
2015.11.01.txt
2015.11.04.txt
2015.11.08.txt
2015.11.09.txt
2015.11.15.txt
Run Code Online (Sandbox Code Playgroud)