Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用于拆分日志文件的Linux shell命令_Linux_Shell_Logging_Split - Fatal编程技术网

用于拆分日志文件的Linux shell命令

用于拆分日志文件的Linux shell命令,linux,shell,logging,split,Linux,Shell,Logging,Split,我想知道是否有更好的方法来拆分日志文本文件,而不是执行下面的shell循环,最好是使用单个shell命令 日志文件如下所示: 2016-11-20T16:19:21+00:00 Logging started 2016-11-20T16:20:41+00:00 System is up 2016-11-20T16:21:07+00:00 Unknown event 45 ... 2016-11-25T08:40:00+00:00 Blah blah 2016-11-25T08:42:00+00:

我想知道是否有更好的方法来拆分日志文本文件,而不是执行下面的shell循环,最好是使用单个shell命令

日志文件如下所示:

2016-11-20T16:19:21+00:00 Logging started
2016-11-20T16:20:41+00:00 System is up
2016-11-20T16:21:07+00:00 Unknown event 45
...
2016-11-25T08:40:00+00:00 Blah blah
2016-11-25T08:42:00+00:00 Blah blah
...
2016-11-27T11:32:00+00:00 System powering down
WHEN='2016-11-25T08:41:00+00:00' # actually that is read as a parameter

while read line; do
  if [ "${line}" \> "${WHEN}" ]; then
    echo "${line}"
  fi
done <"${LOGFILE}" >"${CUTFILE}"
  • 所有行都以ISO8601日期标记(UTC)开始
  • 这些行是按构造按时间顺序排列的,因为当有事件要记录时会追加行
  • 文件正在增长
因此,我们要完成的任务是在给定时间分割文件。 比如说,我只保留了最后一周的条目,以避免不断增长的综合症

因此,由于日期为“2016-11-25T08:41:00+00:00”,我希望只保留该日期之后的条目。 请注意,我们要剪切文件的日期不一定与现有条目对应(如示例中所示)

因此,我所能做的就是编写一段这样的代码:

2016-11-20T16:19:21+00:00 Logging started
2016-11-20T16:20:41+00:00 System is up
2016-11-20T16:21:07+00:00 Unknown event 45
...
2016-11-25T08:40:00+00:00 Blah blah
2016-11-25T08:42:00+00:00 Blah blah
...
2016-11-27T11:32:00+00:00 System powering down
WHEN='2016-11-25T08:41:00+00:00' # actually that is read as a parameter

while read line; do
  if [ "${line}" \> "${WHEN}" ]; then
    echo "${line}"
  fi
done <"${LOGFILE}" >"${CUTFILE}"
WHEN='2016-11-25T08:41:00+00:00'#实际上这是作为参数读取的
读行时;做
如果[“${line}”\>“${WHEN}”];然后
回显“${line}”
fi
完成“${CUTFILE}”
这是可行的,但由于它是一个shell循环,如果文件变得非常大,那么速度可能会很慢


因此,使用标准命令/实用程序有什么更好的建议吗?

您可以使用以下命令:

tail -n +$(cat logfile | grep -m1 -n "2016-11-25" | cut -d: -f1) logfile 
-grep的m1选项将与第一次出现的模式(2016-11-25)匹配,-n将与匹配的模式一起打印相应的行号

e、 上面的日志文件

root@ubuntu:/home# cat logfile 
2016-11-20T16:19:21+00:00 Logging started
2016-11-20T16:20:41+00:00 System is up
2016-11-20T16:21:07+00:00 Unknown event 45
2016-11-25T08:40:00+00:00 Blah blah
2016-11-25T08:39:02+00:00 Blah blah
2016-11-25T08:39:04+00:00 Blah blah
2016-11-25T08:42:00+00:00 Blah blah
2016-11-27T11:32:00+00:00 System powering down
灰色化所需模式“2016-11-25”

要获取上述输出的第一个值,请使用带分隔符的cut命令“:”

并将其传递给tail命令tail-n+,以获得所需的输出

root@ubuntu:/home# tail -n +$(cat logfile | grep -m1 -n "2016-11-25" | cut -d: -f1) logfile
2016-11-25T08:40:00+00:00 Blah blah
2016-11-25T08:39:02+00:00 Blah blah
2016-11-25T08:39:04+00:00 Blah blah
2016-11-25T08:42:00+00:00 Blah blah
2016-11-27T11:32:00+00:00 System powering down

允许您为此使用
awk
吗?不要重新发明轮子。使用。它有很多有趣的选项,比如压缩文件并将其移动到一个目录中,以获取“旧”日志、邮件等等。它评估日志的大小、时间(旋转的频率),但不评估文件内容。我认为你甚至不需要后者。事实上,Ruslan,我需要的正是logrotate+文件内容!如果我没有找到更好的方法,我可能会用logrotate来探索解决方案。谢谢。这是一个非常好的回答@Hardik Sanghvi。(很抱歉,现在还不能“评论”)问题是文件中可能没有拆分日期。请参阅我使用“更大”操作符的原始脚本。因此,当文件中没有拆分日期时(例如,当天没有发生任何事情),grep选项将失败,因为它根本找不到任何内容。