如何加速这个日志解析器?
How to speed up this log parser?
我有一个 GB 大小的日志文件,格式如下:
2016-02-26 08:06:45 Blah blah blah
我有一个日志解析器,它根据日期将单个文件日志拆分成单独的文件,同时从原始行中修剪日期。
我确实想要某种形式的 tee
这样我就可以看到这个过程有多远。
问题是这种方法速度慢得令人麻木。在bash中没有办法快速做到这一点吗?还是我必须编写一些 C 程序才能完成?
log_file=server.log
log_folder=logs
mkdir $log_folder 2> /dev/null
while read a; do
date=${a:0:10}
echo "${a:11}" | tee -a $log_folder/$date
done < <(cat $log_file)
read
在 bash 中慢得离谱。你可以让它更快,但你可以用 awk 获得更快的速度:
#!/bin/bash
log_file=input
log_directory=${1-logs}
mkdir -p $log_directory
awk 'NF>1{d=l"/"; =""; print > d}' l=$log_directory $log_file
如果您确实也想打印到 stdout,可以,但是如果要打印到 tty,速度会大大降低。只需使用:
awk '{d=l"/"; =""; print > d}1' l=$log_directory $log_file
(注意右大括号后的“1”。)
试试这个 awk 解决方案 - 它应该非常快 - 它显示进度 - 只有一个文件保持打开 - 还将不以日期开头的行写入当前日期文件,这样行就不会丢失 - a如果日志以没有日期的行开头,则默认初始日期设置为“0000-00-00”
任何时序比较将不胜感激
dir=
if [[ -z $dir ]]; then
echo >&2 "Usage: [=10=] outdir <logfile"
echo >&2 "outdir: directory where output files are created"
echo >&2 "logfile: input on stdin to split into output files"
exit 1
fi
mkdir -p $dir
echo "output directory \"$dir\""
awk -vdir=$dir '
BEGIN {
datepat="[0-9]{4}-[0-9]{2}-[0-9]{2}"
date="0000-00-00"
file=dir"/"date
}
date != && ~ datepat {
if(file) {
close(file)
print ""
}
print ":"
date=
file=dir"/"date
}
{
if( ~ datepat)
line=substr([=10=],12)
else
line=[=10=]
print line
print line >file
}
'
head -6 $dir/*
示例输入日志
first line without date
2016-02-26 08:06:45 0 Blah blah blah
2016-02-26 09:06:45 1 Blah blah blah
2016-02-27 07:06:45 2 Blah blah blah
2016-02-27 08:06:45 3 Blah blah blah
no date line
blank lines
another no date line
2016-02-28 07:06:45 4 Blah blah blah
2016-02-28 08:06:45 5 Blah blah blah
输出
first line without date
2016-02-26:
08:06:45 0 Blah blah blah
09:06:45 1 Blah blah blah
2016-02-27:
07:06:45 2 Blah blah blah
08:06:45 3 Blah blah blah
no date line
blank lines
another no date line
2016-02-28:
07:06:45 4 Blah blah blah
08:06:45 5 Blah blah blah
==> tmpd/0000-00-00 <==
first line without date
==> tmpd/2016-02-26 <==
08:06:45 0 Blah blah blah
09:06:45 1 Blah blah blah
==> tmpd/2016-02-27 <==
07:06:45 2 Blah blah blah
08:06:45 3 Blah blah blah
no date line
blank lines
another no date line
==> tmpd/2016-02-28 <==
07:06:45 4 Blah blah blah
08:06:45 5 Blah blah blah
我有一个 GB 大小的日志文件,格式如下:
2016-02-26 08:06:45 Blah blah blah
我有一个日志解析器,它根据日期将单个文件日志拆分成单独的文件,同时从原始行中修剪日期。
我确实想要某种形式的 tee
这样我就可以看到这个过程有多远。
问题是这种方法速度慢得令人麻木。在bash中没有办法快速做到这一点吗?还是我必须编写一些 C 程序才能完成?
log_file=server.log
log_folder=logs
mkdir $log_folder 2> /dev/null
while read a; do
date=${a:0:10}
echo "${a:11}" | tee -a $log_folder/$date
done < <(cat $log_file)
read
在 bash 中慢得离谱。你可以让它更快,但你可以用 awk 获得更快的速度:
#!/bin/bash
log_file=input
log_directory=${1-logs}
mkdir -p $log_directory
awk 'NF>1{d=l"/"; =""; print > d}' l=$log_directory $log_file
如果您确实也想打印到 stdout,可以,但是如果要打印到 tty,速度会大大降低。只需使用:
awk '{d=l"/"; =""; print > d}1' l=$log_directory $log_file
(注意右大括号后的“1”。)
试试这个 awk 解决方案 - 它应该非常快 - 它显示进度 - 只有一个文件保持打开 - 还将不以日期开头的行写入当前日期文件,这样行就不会丢失 - a如果日志以没有日期的行开头,则默认初始日期设置为“0000-00-00”
任何时序比较将不胜感激
dir=
if [[ -z $dir ]]; then
echo >&2 "Usage: [=10=] outdir <logfile"
echo >&2 "outdir: directory where output files are created"
echo >&2 "logfile: input on stdin to split into output files"
exit 1
fi
mkdir -p $dir
echo "output directory \"$dir\""
awk -vdir=$dir '
BEGIN {
datepat="[0-9]{4}-[0-9]{2}-[0-9]{2}"
date="0000-00-00"
file=dir"/"date
}
date != && ~ datepat {
if(file) {
close(file)
print ""
}
print ":"
date=
file=dir"/"date
}
{
if( ~ datepat)
line=substr([=10=],12)
else
line=[=10=]
print line
print line >file
}
'
head -6 $dir/*
示例输入日志
first line without date
2016-02-26 08:06:45 0 Blah blah blah
2016-02-26 09:06:45 1 Blah blah blah
2016-02-27 07:06:45 2 Blah blah blah
2016-02-27 08:06:45 3 Blah blah blah
no date line
blank lines
another no date line
2016-02-28 07:06:45 4 Blah blah blah
2016-02-28 08:06:45 5 Blah blah blah
输出
first line without date
2016-02-26:
08:06:45 0 Blah blah blah
09:06:45 1 Blah blah blah
2016-02-27:
07:06:45 2 Blah blah blah
08:06:45 3 Blah blah blah
no date line
blank lines
another no date line
2016-02-28:
07:06:45 4 Blah blah blah
08:06:45 5 Blah blah blah
==> tmpd/0000-00-00 <==
first line without date
==> tmpd/2016-02-26 <==
08:06:45 0 Blah blah blah
09:06:45 1 Blah blah blah
==> tmpd/2016-02-27 <==
07:06:45 2 Blah blah blah
08:06:45 3 Blah blah blah
no date line
blank lines
another no date line
==> tmpd/2016-02-28 <==
07:06:45 4 Blah blah blah
08:06:45 5 Blah blah blah