Bash 在两个模式之间搜索和捕获多个组

Bash 在两个模式之间搜索和捕获多个组,bash,awk,sed,grep,Bash,Awk,Sed,Grep,我需要捕获以ORA-01555及其相关SQL语句开头的行的警报日志内容 文件内容如下: Sat Oct 21 12:11:40 2017 Thread 1 advanced to log sequence 143 (LGWR switch) Current log# 5 seq# 143 mem# 0: Sat Oct 21 12:12:22 2017 Thread 1 cannot allocate new log, sequence 144 Private strand flush no

我需要捕获以ORA-01555及其相关SQL语句开头的行的警报日志内容

文件内容如下:

Sat Oct 21 12:11:40 2017
Thread 1 advanced to log sequence 143 (LGWR switch)
  Current log# 5 seq# 143 mem# 0:
Sat Oct 21 12:12:22 2017
Thread 1 cannot allocate new log, sequence 144
Private strand flush not complete
  Current log# 5 seq# 143 mem# 0:
Sat Oct 21 12:12:22 2017
ORA-01555 caused by SQL statement below (SQL ID: 1sfgms7z66zrs, SCN: 0x0401.1e45bbc4):
Sat Oct 21 12:11:48 2017
CREATE INDEX AAD_SAA_ADB_RESULTS_AUD_GTI1 ON AAD_PS_SAA_ADB_RESULTS_AUD_GT (
 rpt_date
)
Sat Oct 21 12:20:56 2017
Thread 1 advanced to log sequence 153 (LGWR switch)
  Current log# 6 seq# 153 mem# 0: 
+REDO_VOL1/DSS1STG/ONLINELOG/group_6.262.957710915
  Current log# 6 seq# 153 mem# 1: 
+REDO_VOL1/DSS1STG/ONLINELOG/group_6.263.957710917
Sat Oct 21 12:21:11 2017
ORA-01555 caused by SQL statement below (SQL ID: 9ad5awvfvsfd9, Query 
Duration=6444 sec, SCN: 0x0401.1e53de65):
Sat Oct 21 12:21:11 2017
SELECT a.EMPLID,    a.TEST_ID,    a.TEST_COMPONENT,    a.SCORE
    FROM
    ODS_PSE.PS_STDNT_TEST_COMP a,
    DSS_RDS.IR_STU_TST_SCR_SAT_VLD_DT_ST b
    where
    a.TEST_COMPONENT in ('VE','MA')
    AND a.EMPLID = b.PRSN_UNIV_ID
    AND ROUND(a.SCORE) = a.SCORE
    AND a.TEST_ID = b.STU_TST_CD
    AND a.TEST_DT = b.TEST_DT
    AND a.LS_DATA_SOURCE = b.LS_DATA_SOURCE
UNION
    SELECT a.EMPLID,    a.TEST_ID,    a.TEST_COMPONENT,    a.SCORE
    FROM
    ODS_PSE.PS_STDNT_TEST_COMP a,
    DSS_RDS.IR_STU_TST_SCR_SAT_VLD_DT_ST b
    where
    a.TEST_COMPONENT in ('ERWS','MSS','MT','RT','WLT') 
    AND a.EMPLID = b.PRSN_UNIV_ID
    AND ( 
            (ROUND(a.SCORE) = a.SCORE and a.TEST_COMPONENT in 
('ERWS','MSS','RT','WLT'))
        or  (a.SCORE BETWEEN 10 AND 40  and a.TEST_COMPONENT in ('MT'))
        )
    AND a.TEST_ID = b.STU_TST_CD
    AND a.TEST_DT = b.TEST_DT
    AND a.LS_DATA_SOURCE = b.LS_DATA_SOURCE
Sat Oct 21 13:05:01 2017
Thread 1 advanced to log sequence 173 (LGWR switch)
  Current log# 5 seq# 173 mem# 0:     +REDO_VOL1/DSS1STG/ONLINELOG/group_5.257.957710909
  Current log# 5 seq# 173 mem# 1:     +REDO_VOL1/DSS1STG/ONLINELOG/group_5.256.957710911
我要捕获的内容是:

ORA-01555 caused by SQL statement below (SQL ID: 1sfgms7z66zrs, SCN: 0x0401.1e45bbc4):
Sat Oct 21 12:11:48 2017
CREATE INDEX AAD_SAA_ADB_RESULTS_AUD_GTI1 ON AAD_PS_SAA_ADB_RESULTS_AUD_GT (
 rpt_date
)
ORA-01555 caused by SQL statement below (SQL ID: 9ad5awvfvsfd9, Query 
Duration=6444 sec, SCN: 0x0401.1e53de65):
Sat Oct 21 12:21:11 2017
SELECT a.EMPLID,    a.TEST_ID,    a.TEST_COMPONENT,    a.SCORE
    FROM
    ODS_PSE.PS_STDNT_TEST_COMP a,
    DSS_RDS.IR_STU_TST_SCR_SAT_VLD_DT_ST b
    where
    a.TEST_COMPONENT in ('VE','MA')
    AND a.EMPLID = b.PRSN_UNIV_ID
    AND ROUND(a.SCORE) = a.SCORE
    AND a.TEST_ID = b.STU_TST_CD
    AND a.TEST_DT = b.TEST_DT
    AND a.LS_DATA_SOURCE = b.LS_DATA_SOURCE
UNION
    SELECT a.EMPLID,    a.TEST_ID,    a.TEST_COMPONENT,    a.SCORE
    FROM
    ODS_PSE.PS_STDNT_TEST_COMP a,
    DSS_RDS.IR_STU_TST_SCR_SAT_VLD_DT_ST b
    where
    a.TEST_COMPONENT in ('ERWS','MSS','MT','RT','WLT') 
    AND a.EMPLID = b.PRSN_UNIV_ID
    AND ( 
            (ROUND(a.SCORE) = a.SCORE and a.TEST_COMPONENT in 
('ERWS','MSS','RT','WLT'))
        or  (a.SCORE BETWEEN 10 AND 40  and a.TEST_COMPONENT in ('MT'))
        )
    AND a.TEST_ID = b.STU_TST_CD
    AND a.TEST_DT = b.TEST_DT
    AND a.LS_DATA_SOURCE = b.LS_DATA_SOURCE
这是我正在使用的grep,但正如您在结果中看到的,它没有捕获每个ORA-01555行及其整个SQL语句的内容。不确定为什么我的消极前瞻不起作用:

grep -Pzo 'ORA-01555.*\n(^.*[0-9]{2}:[0-9]{2}:[0-9]{2}.*)\n.*(?!.*[0-9]{2}:[0-9]{2}.*\n).+' alert.log

ORA-01555 caused by SQL statement below (SQL ID: 1sfgms7z66zrs, SCN: 0x0401.1e45bbc4):
Sat Oct 21 12:11:48 2017
CREATE INDEX AAD_SAA_ADB_RESULTS_AUD_GTI1 ON AAD_PS_SAA_ADB_RESULTS_AUD_GT (
ORA-01555 caused by SQL statement below (SQL ID: 9ad5awvfvsfd9, Query Duration=6444 sec, SCN: 0x0401.1e53de65):
Sat Oct 21 12:21:11 2017
SELECT a.EMPLID,    a.TEST_ID,    a.TEST_COMPONENT,    a.SCORE

awk解决方案:

awk '/ORA-01555/{ f=1 }f && /^[A-Z][a-z]{2} .* [0-9]{4}$/{ date++; if(date>=2) f=date=0 }f' alert.log

您可以尝试此sed命令

sed -E '/ORA-01555/!d;:A;N;/\n[A-Za-z]{3} [A-Za-z]{3} [0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2} [0-9]{4}$/!bA;:B;N;/\n[A-Za-z]{3} [A-Za-z]{3} [0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2} [0-9]{4}$/!bB;s/(.*)\n.*/\1/' infile
如果一行包含ORA-01555-->请保留在空格中

趁下一行不是约会的时候,在Patren space中选择下一行

将第一个日期保留在空白处

当不是约会时,继续下一行

删除父空间中的最后一行,即日期


打印父空间并返回到起始处,以使用ORA-01555查找新行。

Hmm,这将返回整个文件内容。不是我在看的for@BillMyers我对此表示怀疑。这个截图是你的朋友毫无疑问,这就是我要找的朋友,但我得到了整个文件。您正在运行哪个版本的awk?我在RHEL 6.9和GNU Awk 3.1.7上。搞定了!谢谢ctac。