显示与模式匹配的行以及每行之前的 4 行

显示与模式匹配的行以及每行之前的 4 行

例如,从此文件中:

CREATE SYNONYM I801XS07 FOR I8010.I801XT07
               *
ERROR at line 1:
ORA-00955: name is already used by an existing object


CREATE SYNONYM I801XS07 FOR I8010.I801XT07
               *
ERROR at line 1:
ORA-00955: name is already used by an existing object



Table altered.


Table altered.


Table altered.


Table altered.


Table altered.


Table altered.


Table altered.


Table altered.

DROP INDEX I8011I01
           *
ERROR at line 1:
ORA-01418: specified index does not exist



Index created.

我想要一种方法来查找ORA-并显示该ORA-行和前 4 行:

CREATE SYNONYM I801XS07 FOR I8010.I801XT07
               *
ERROR at line 1:
ORA-00955: name is already used by an existing object

CREATE SYNONYM I801XS07 FOR I8010.I801XT07
               *
ERROR at line 1:
ORA-00955: name is already used by an existing object

DROP INDEX I8011I01
           *
ERROR at line 1:
ORA-01418: specified index does not exist

答案1

选项-B正是grep这样做的: grep -B 4 ORA- your_file.

在没有 GNU 的情况下grep,我改编了grep4来自grymoire sed 教程:

#!/bin/sh

# grepB4: prints out 4 lines before and the line including pattern
# if there is only one argument, exit

case $# in 
    1);;
    *) echo "Usage: $0 pattern";exit;;
esac;

sed -n '
'/"$1"/' !{
    # does not match - add this line to the hold space
    H
    # bring it back into the pattern space
    x
    # Two lines would look like .*\n.*
    # Three lines look like .*\n.*\n.*
    # Delete extra lines - keep four
    s/^.*\n\(.*\n.*\n.*\n.*\)$/\1/
    # put it back in hold space
    x
}
'/"$1"/' {
    # matches - append the current line
    H
    # bring hold space contents into pattern space
    g
    # print the 4 lines
    p
    # add the mark
    a\
---
}'

用法:grepB4 pattern < file

布鲁斯·艾迪格回答本质上与 做同样的事情awk,它的语法通常比 更少神秘sed

答案2

假设您使用的是旧系统,例如 HP-UX,它没有 GNU 实用程序,只有旧的、原始的 BSD 或 AT&T“grep”。你可以这样做:

#!/bin/sh

awk '/ORA-/ { print line1; print line2; print line3; print line4; print $0 }\
// {line1 = line2; line2 = line3; line3 = line4; line4 = $0}' $1

是的,有大量的边缘条件是不正确的,但是你想要什么?另外,考虑到您正在使用一些已解码、过时的操作系统和硬件,您可能没有足够的 CPU 能力来处理花哨的错误。

答案3

awk 'NR == FNR && $0 ~ p {
  for (i = FNR; i >= FNR - l; i--)
    nr[i]; next
  }
FNR in nr  
BEGIN {
  ARGV[ARGC++] = ARGV[ARGC - 1]
  }' l=4 p=ORA- infile   

在 Solaris 上使用诺克或者/usr/xpg4/bin/awk

相关内容