【问题标题】:Print whole log starting with special character打印以特殊字符开头的整个日志
【发布时间】:2019-03-29 13:30:18
【问题描述】:

我正在尝试从日志文件中打印一些日志以用于警报报告工具,我只需要过滤那些以 ** 等特殊字符开头的日志。 请在此处找到日志文件中一些文本的示例。(图片)

到目前为止,我设法在 SOH 字符之间打印日志,如下所示,但我无法找出如何仅打印以“**”开头的日志,所以我想打印如下所示的日志”

日志文件内容:

      SOH
     +++ skdfhahjsahsdjk >
    ** ALPHA EDFJDJFKLJDKFJKSDLFJL
       SDFSDGDRGRTG
       WEFETTFYRT #168113++-
   SOH 
       +++ skdfhahjsahsdjk >
    * KJENRFKES DFJKLSDFJEDFJDJFKLJDKFJKSDLFJL
       SDFSDGDRGRTG
       WEFETTFYRT #168113++-
   SOH 
       +++ skdfhahjsahsdjk >
    CL mesukww juwaehdiearfa
       SDFSDGDRGRTG
       WEFETTFYRT #168113++-
    SOH
       +++ skdfhahjsahsdjk >
    *C KJENRFKESDFJ ksludhieokdaewmdp
       SDFSDGDRGRTG
       WEFETTFYRT #168113++-
    SOH
     +++ skdfhahjsahsdjk >
    ** ALPHA EDFJDJFKLJDKFJKSDLFJL
       SDFSDGDRGRTG
       WEFETTFYRT #168113++-

到目前为止,我设法通过

打印 SOH 字符(在日志上方)之间的日志

cat OMlog5|awk -F'[|^A^A]'> 测试3


我也试过下面的命令,过滤那些以 ^* 开头的,但它只打印出以 * 开头的特定行,而不是整个日志

结果:

cat OMlog5|awk -F'[|^A^A]' '{print $0}'|grep "^*" >Test4 :


** KDHFGJHSDGDJLKSGJKFJJ

我希望是:

 +++ skdfhahjsahsdjk >
** KJENRFKESDFJKLSDFJEDFJDJFKLJDKFJKSDLFJL
   SDFSDGDRGRTG
   WEFETTFYRT #168113++-

你能帮忙找到正确的命令吗?

提前致谢!

我试图避免打印特定记录,例如与“ALPHA”相关的日志。我尝试通过此代码但未成功:

cat logfile |grep -v "ALPHA"> result_log

在这个之后,它把我打印出来:

+++ skdfhahjsahsdjk >
       SDFSDGDRGRTG
       WEFETTFYRT #168113++-

我希望不打印以上与 alpha 相关的整个日志。 你能帮忙吗?

【问题讨论】:

  • 一段时间后,当您向问题添加新要求且答案已被接受时,这会让人感到困惑。 我建议在此处恢复更改。 而是写一个新问题,其中包含指向此问题的链接以及对差异或附加要求的解释。显示新需求的示例输入、到目前为止您实际使用的过滤脚本(没有新需求)以及您建议的修改或附加脚本/命令。在cat logfile |grep -v "ALPHA"> result_log 中,不清楚logfile 是您的原始日志文件还是第一个处理步骤的结果。

标签: linux


【解决方案1】:

这可能更容易记住并且在日志格式在行数方面保持一致的情况下起作用:

awk -F 'SOH' '{print $1}' log.txt | grep -B1 -A2 '^\*\*'

它的工作方式首先是获取由SOH分隔的组:

$ awk -F 'SOH' '{print $1}' log.txt
+++ skdfhahjsahsdjk >
** KJENRFKESDFJKLSDFJEDFJDJFKLJDKFJKSDLFJL
SDFSDGDRGRTG
WEFETTFYRT #168113++-

+++ skdfhahjsahsdjk >
* KJENRFKESDFJKLSDFJEDFJDJFKLJDKFJKSDLFJL
SDFSDGDRGRTG
WEFETTFYRT #168113++-

+++ skdfhahjsahsdjk >
CL KJENRFKESDFJKLSDFJEDFJDJFKLJDKFJKSDLFJL
SDFSDGDRGRTG
WEFETTFYRT #168113++-

+++ skdfhahjsahsdjk >
*C KJENRFKESDFJKLSDFJEDFJDJFKLJDKFJKSDLFJL
SDFSDGDRGRTG
WEFETTFYRT #168113++-

然后您可以简单地使用grep 从您的模式^\*\* 中获取-B1 之前的一行和-A2 之后的两行:

grep -B1 -A2 '^\*\*'

这将从您的示例中返回:

+++ skdfhahjsahsdjk >
** KJENRFKESDFJKLSDFJEDFJDJFKLJDKFJKSDLFJL
SDFSDGDRGRTG
WEFETTFYRT #168113++-

如果您不关心第一个分隔符SOH,那么您可以这样做:

grep -B1 -A2 '^\*\*' log.txt

如果你的日志以额外的空格开头,你可以使用这个正则表达式:

grep -B1 -A2 '^\s*\*\*' | grep -v -- --

多余的|grep -v -- --是去掉--分隔符

或者如果在 Linux 中你可以使用 --no-group-separator:

grep -B1 -A2 '^\s*\*\*' --no-group-separator

【讨论】:

  • 非常感谢您的建议。它工作得很好,但我不明白为什么它在每个日志之间的输出“--”中也包含一个符号
  • 斜体 粗体 -- +++ skdfhahjsahsdjk > * KJENRFKESDFJKLSDFJEDFJDJFKLJDKFJKSDLFJL SDFSDGDRGRTG WEFETTFYRT #168113++- -- +++ skdfhahjsahsdjk > CL KJENRFKESDFJKLSDFJEDFJDJFKLJDKFJKSDLFJL SDFSDGDRGRTG WEFETTFYRT #168113++
  • 非常感谢您的支持!该代码有效,但我不明白为什么它会在每个日志的开头添加一个额外的字符?
  • @Dominik 嗨,确实有一些 grep 分隔符,尝试将输出通过管道传输到 |grep -v -- --,或者如果在 Linux 中使用 --no-group-separator,请检查更新的答案,
  • 感谢您的解决方案,它按预期工作。只有一个问题:有没有其他方法可以打印分隔符 ^A(SOH) 之间的所有行而不计算 ** -grep -B1 -A2 之后的行?原因并非所有日志在 ** 之后都有 3 行。我还有一些其他的在 ** 之后多于或少于 2 行?
【解决方案2】:

如果此块包含以** 开头的行(在可选空格之后),则此awk 命令将打印两个SOH 行之间或最后SOH 行之后的所有内容。
编辑:根据新要求,脚本现在搜索正好有两个星号 (*) 而不是至少两个星号的行。

awk '/^[    ]*SOH[  ]*$/ {                # match SOH line
   if(found && length(buf)>0) print buf;  # print old buffer
   buf="";                                # clear buffer
   found=0;                               # no ** line yet
   skip=1;                                # do not add SOH line to buffer
}
/^[     ]*\*\*[     ]/ { found=1;}        # ** line found. Edit: The second [   ] (with space and tab) makes sure there are exactly two *
{                                         # for any line...
   if(!skip) buf=buf  $0  "\n";           # add line to buffer (except SOH)
   skip=0;                                # do not skip next line
}
END {                                     # to handle matching last record
   if(found && length(buf)>0) print buf;  # print old buffer
}' logfile

注意:括号[ ] 之间有一个空格和一个制表符。 ([ ^I])

当我使用带有问题中显示的内容的logfile(在“日志文件内容:”下方)作为脚本的输入时,结果输出是

     +++ skdfhahjsahsdjk >
    ** KJENRFKESDFJKLSDFJEDFJDJFKLJDKFJKSDLFJL
       SDFSDGDRGRTG
       WEFETTFYRT #168113++-

前导空格与下面问题“我期望是:”中显示的输出不同,因为问题中的日志文件内容具有更多前导空格。

【讨论】:

  • 感谢您提供的解决方案,但我认为不适合这种情况。SOH 是日志分隔符,而“**”是日志的一部分,我们不能将其作为条件的开始和结束日志。如果我错了,请纠正
  • @Dominik 我不明白你的评论。我刚刚修复了我的脚本中的一个错误:在单引号之间的awk sript (') 我不能在 cmets 中使用单引号,例如# don't 除此之外,脚本会产生正确的输出,如问题所示。
  • :是的,你是对的,脚本完美运行 :)。多谢。我错过了脚本中的 smth,它在第一次尝试时不起作用,但现在输出符合预期。 :)
  • @Dominik 请编辑您的问题并添加此新要求。明确说明您是稍后添加的。
  • 脚本按预期工作,非常感谢。我有一个日志文件以 *、** 和其他甚至以 ***** 开头的文件。我的要求是如何使用脚本仅打印**,我如何强制仅打印**且不大于**?你能帮忙吗?
猜你喜欢
  • 2016-07-26
  • 2021-01-05
  • 1970-01-01
  • 1970-01-01
  • 2018-05-03
  • 1970-01-01
  • 2014-07-27
  • 1970-01-01
相关资源
最近更新 更多