【问题标题】:print lines in a range pattern from a text file [closed]从文本文件中以范围模式打印行[关闭]
【发布时间】:2023-03-22 13:29:01
【问题描述】:

我有文件 log.txt :

======================
Tue Jun 25 00:02:00 WIT 2013
======================


pool
    INFO     name               work
    INFO     threads.total      30
    INFO     threads.active     7
    INFO     threads.waiting    23
    INFO     jobs.queue.latency 0
    INFO     jobs.run.latency   139
    INFO     jobs.queue.tps     3
    INFO     jobs.start.tps     3
    INFO     jobs.finish.tps    3
    NORMAL   jobs.count         0
pool
    INFO     name               recv
    INFO     threads.total      40
    INFO     threads.active     27
    INFO     threads.waiting    13
    INFO     jobs.queue.latency 0
    INFO     jobs.run.latency   0
    INFO     jobs.queue.tps     0
    INFO     jobs.start.tps     0
    INFO     jobs.finish.tps    0
    NORMAL   jobs.count         0
pool
    INFO     name               send
    INFO     threads.total      10
    INFO     threads.active     0
    INFO     threads.waiting    10
    INFO     jobs.queue.latency 0
    INFO     jobs.run.latency   1
    INFO     jobs.queue.tps     5
    INFO     jobs.start.tps     5
    INFO     jobs.finish.tps    5
    NORMAL   jobs.count         0


======================
Tue Jun 25 00:03:00 WIT 2013
======================

pool
    INFO     name               work
    INFO     threads.total      30
    INFO     threads.active     15
    INFO     threads.waiting    15
    INFO     jobs.queue.latency 0
    INFO     jobs.run.latency   13
    INFO     jobs.queue.tps     1
    INFO     jobs.start.tps     0
    INFO     jobs.finish.tps    0
    NORMAL   jobs.count         46
    INFO     jobs.1.type        request

pool
    INFO     name               recv
    INFO     threads.total      40
    INFO     threads.active     27
    INFO     threads.waiting    13
    INFO     jobs.queue.latency 0
    INFO     jobs.run.latency   0
    INFO     jobs.queue.tps     0
    INFO     jobs.start.tps     0
    INFO     jobs.finish.tps    0
    NORMAL   jobs.count         0
pool
    INFO     name               send
    INFO     threads.total      10
    INFO     threads.active     0
    INFO     threads.waiting    10
    INFO     jobs.queue.latency 0
    INFO     jobs.run.latency   0
    INFO     jobs.queue.tps     0
    INFO     jobs.start.tps     0
    INFO     jobs.finish.tps    0
    NORMAL   jobs.count         0

我想要这样的结果:


======================
Tue Jun 25 00:03:00 WIT 2013
======================
    INFO     name               work
    NORMAL   jobs.count         46
    INFO     jobs.1.type        request

我已经使用了:

cat log.txt |grep -B14 -A1 -i 'jobs.count         [1-9]\{2,\}' |
egrep -i "jobs.1.type|=|WIT|jobs.count         [1-9]"

如果名称不是“work”而是“send”或“recv”,那么“grep -B14”将无法获取日期。 还有其他解决方案吗?另一方面,如果“jobs.count”不是“0”而不是get date =“Tue Jun 25 00:03:00 WIT 2013”​​,我想要grep,get name =“INFO name work”并获得工作类型“INFO jobs .1.类型请求”:

【问题讨论】:

  • 欢迎来到 Stack Overflow。请尽快阅读FAQ。我试图更清楚地格式化你的问题,但我还不确定它是否正确。我也很不清楚你在问什么。要将代码和日志文件等显示为等宽字体,请选择代码,然后使用编辑框上方的 {} 按钮。这会将代码统一缩进 4 个空格,从而产生恒定宽度的布局。破折号和等号线在第 1 列时会产生格式效果。
  • 是的,这是我的问题。感谢您的编辑
  • 当计数是 10 的偶数倍时,您的正则表达式将无法匹配。您可能需要 [1-9][0-9]*,或者如果零也是有效结果,则只需 [0-9]+

标签: regex perl sed awk pattern-matching


【解决方案1】:

GNU 代码

/WIT|INFO +name|jobs.1.type|jobs.count +[1-9]/{
if ($0 ~ /WIT/)
    {cheader=$0}
if ($0 ~ /INFO +name/)
    {cname=$0}
if ($0 ~ /jobs.count +[1-9]/)
    {ccount=$0}
if ($0 ~ /jobs.1.type/)
    {
    i++
    header[i]=cheader
    name[i]=cname
    count[i]=ccount
    type[i]=$0
    }
}
END {
    line="======================"
    for (a=1 ;a<=i ;a++)
    {
    if (count[a] != "")
        {
        print line
        print header[a]
        print line
        print name[a]
        print count[a]
        print type[a]
        }
    }
}

输出示例:

$awk -f c.awk 文件 ======================= 2013 年 6 月 25 日星期二 00:03:00 ======================= INFO 名称工作 正常工作。计数 46 INFO jobs.1.type 请求

【讨论】:

  • 如果header 下有多个pooljobs.count &gt; 0,这真的有效吗?因为您只使用新标题增加 i
  • @Qben 是的,你是对的,谢谢。来源是“尴尬”,我把计数器放在jobs.1.type。但这可能还不够,可能需要为每个字段设置一个计数器。有点像array of counters
  • 嗨@Qben,感谢工作完美我只是编辑“if ($0 ~ /jobs.count +[1-9]/)”变成“if ($0 ~ /jobs.count +[1- 9][0-9][0-9]/)" 所以只打印 3 位数的 jobscount (jobs.count > 100)
【解决方案2】:
awk '/WIT/ {date=$0} /name/ {printf "\n%s\n%s\n", date, $0} /count|type/' file | 
awk -v RS="" '{for (i=1; i<=NF; i++) if ($i~/count/ && $(i+1)>0) {print; break}}'
Tue Jun 25 00:03:00 WIT 2013
    INFO     name               work
    NORMAL   jobs.count         46
    INFO     jobs.1.type        request

第一个 awk 打印包含日期和所需字段的段落。
第二个 awk 读取段落,只打印 count > 0 的段落。

【讨论】:

  • \n....|..RS="".. 非常好,真的优雅
  • 糟糕,逻辑错误。我需要检查“计数”之后的字段是否不为零。我正在检查 last 字段(即“请求”)> 0
猜你喜欢
  • 1970-01-01
  • 2013-06-25
  • 2023-02-16
  • 2013-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多