shell bash脚本-使用grep的if语句

0s0u357o  于 2023-03-03  发布在  Shell
关注(0)|答案(2)|浏览(189)

前言,我是新的bash脚本,并试图解析日志文件和输出的信息,我正在寻找到一个txt文件。
我的脚本已经有了一个开始,但是我现在被一个条件语句卡住了,我不确定grep现在是最好的用例,也许awk或sed。
文件内容示例:

2022-1-3 14:00:00 ERROR THREAD234 - error info here 
2022-1-4 02:00:00 WARNI THREAD235 - warning info here 
additional warning info here, sometimes includes word error, but i do not want to capture this additional line as it is a warning
2022-2-3 01:00:00 ERROR THREAD333 - error info here2 
error info continued, sometimes there are multiple lines to an error and they do not all include the word error. however, these additional lines to do not include date/times. these are typically stack traces. 
2023-3-4 11:00:00 INFO0 THREAD333 - info here
2022-2-5 01:00:00 ERROR THREAD333 - error info here3
2022-2-6 06:00:00 ERROR THREAD333 - error info here3

期望输出:
电流输出:
我的最终目标:我试图只获取错误及其下一行,如果它是关于该错误的连续信息。我的想法是使用条件if。如果ERROR的下一行没有以日期开头,则打印。如果它以日期开头,则只打印错误。
我不希望在输出中包含日期、时间或线程,也不希望错误信息在输出中重复出现。
目前我使用bash脚本的地方,它确实可以工作,但是我需要对它进行微调,如果错误仍然存在,我需要使用包含下一行的条件。

#!/bin/bash

read -p "File path to log, no spaces: " file
outputFile=Desktop/errorOutput.txt
error=$(grep ERROR $file | cut -b 25-32,47-1000 | sort | uniq -c)
touch $outputFile
echo "$error" > $outputFile
cat $outputFile

我尝试了一个if语句,但是逻辑上有缺陷,我现在尝试用awk来解决这个问题。

kx5bkwkv

kx5bkwkv1#

使用GNU AWK的一个可能的解决方案是:

awk 'BEGIN{RS="[[:digit:]-]+ [[:digit:]:]+ "; ORS=""
           PROCINFO["sorted_in"]="@ind_str_asc"}
     /ERROR/ {gsub("THREAD.* -", "-", $0); !a[$0]++} 
     END{for (i in a) {print a[i], i}}' logfile
1 ERROR - error info here
1 ERROR - error info here2
error info continued, sometimes there are multiple lines to an error and they do not all include the word error. however, these additional lines to do not include date/times. these are typically stack traces.
2 ERROR - error info here3
wr98u20j

wr98u20j2#

下面是一个Ruby可以做到这一点:

ruby -e '
$<.read.scan(/(ERROR[\s\S]*?)(?=^\d{4}|\z)/).  # find the error to next date
    flatten(1).                                # remove one match level
    map(&:strip).                              # remove " \n" at end
    map{|e| e.sub(/^(ERROR\s+)[^-]+/,"\\1")}.  # remove THREAD part
    group_by{|e| e[/ERROR\s+-\s+.*$/]}.        # group by error tag
    map{|k,v| puts "#{v.length} #{v[0]}"}         # print them
' file

图纸:

相关问题