3

基本上,oracle 审计条目作为.aud文件存储在我的 AIX 系统中

/oracle/SBX/saptrace/audit/

这些文件的条目如下所示:

Tue Jul  2 08:41:53 2013 +02:00
LENGTH : '159'
ACTION :[6] 'COMMIT'
DATABASE USER:[1] '/'
PRIVILEGE :[6] 'SYSDBA'
CLIENT USER:[6] 'orasbx'
CLIENT TERMINAL:[5] 'pts/0'
STATUS:[1] '0'
DBID:[10] '1854349635'

Tue Jul  2 08:41:53 2013 +02:00
LENGTH : '159'
ACTION :[6] 'COMMIT'
DATABASE USER:[1] '/'
PRIVILEGE :[6] 'SYSDBA'
CLIENT USER:[6] 'orasbx'
CLIENT TERMINAL:[5] 'pts/0'
STATUS:[1] '0'
DBID:[10] '1854349635'

Tue Jul  2 08:42:16 2013 +02:00
LENGTH : '222'
ACTION :[68] 'update SAPPRD.USR02 set uflag=64 where BNAME='CANAS' and MANDT='000''
DATABASE USER:[1] '/'
PRIVILEGE :[6] 'SYSDBA'
CLIENT USER:[6] 'orasbx'
CLIENT TERMINAL:[5] 'pts/0'
STATUS:[1] '0'
DBID:[10] '1854349635'

现在我在 crontab 中安排了一个 shell 脚本,让它每三个小时运行一次。

脚本是这样的:

#/bin/sh
grep -i USR02 /oracle/SBX/saptrace/audit/*.aud > /EDB/log/check_audit_dest.log
grep -i USH02 /oracle/SBX/saptrace/audit/*.aud >> /EDB/log/check_audit_dest.log
grep -i TCURR /oracle/SBX/saptrace/audit/*.aud >> /EDB/log/check_audit_dest.log
grep -i REGUH /oracle/SBX/saptrace/audit/*.aud >> /EDB/log/check_audit_dest.log
grep -i LFB1 /oracle/SBX/saptrace/audit/*.aud >> /EDB/log/check_audit_dest.log
grep -i LFA1 /oracle/SBX/saptrace/audit/*.aud >> /EDB/log/check_audit_dest.logs

该脚本的作用是,如果这些表有任何操作,它将将该行记录到 /EDB/log/check_audit_dest.log

像这样:

# cat /EDB/log/check_audit_dest.log
/oracle/SBX/saptrace/audit/sbx_ora_13828348_1.aud:ACTION :[68] 'update SAPPRD.USR02 set uflag=64 where BNAME='CANAS' and MANDT='000''
/oracle/SBX/saptrace/audit/sbx_ora_8847374_1.aud:ACTION :[67] 'update SAPPRD.USR02 set uflag=0 where BNAME='CANAS' and MANDT='000''

现在我想要的是除了该行之外,我还希望每个条目的第一行都登录到该日志文件中(例如:)Tue Jul 2 08:42:16 2013 +02:00

谢谢

4

3 回答 3

3

鉴于您发布的示例输入,您只需要:

$ awk -v RS= -F'\n' '/USR02|USH02|TCURR|REGUH|LFB1|LFA1/ {print FILENAME, $1, $3}' file
file Tue Jul  2 08:42:16 2013 +02:00 ACTION :[68] 'update SAPPRD.USR02 set uflag=64 where BNAME='CANAS' and MANDT='000''

如果这样做不行,请发布一些更具代表性的输入和预期输出。

fedorqui 要求的解释如下

  • RS==> 记录由空行分隔
  • -F'\n'=> 记录中的字段由换行符分隔
  • /USR02|USH02|TCURR|REGUH|LFB1|LFA1/=> 查找包含任何 -|分隔字符串的记录
  • print FILENAME, $1, $3=> 打印当前文件的名称,以及当前记录的第 1 行和第 3 行/字段,第 1 行是日期,第 3 行是 ACTION。
于 2013-07-29T16:42:36.427 回答
2

Ed Morton 给出了一个 awk 解决方案,其中包括设置RSFS. 这是 awk 的另一个解决方案:

awk '!$0{delete a;next}{a[NR]=$0}/USR02|USH02|TCURR|REGUH|LFB1|LFA1/{print a[NR-2];print $0}' file

!$0{delete a;next}如果您的文件不是一个巨大的怪物,则可以删除第一部分:

awk '{a[NR]=$0}/USR02|USH02|TCURR|REGUH|LFB1|LFA1/{print a[NR-2];print $0}' file

输出与您的输入:

kent$  awk '{a[NR]=$0}/USR02|USH02|TCURR|REGUH|LFB1|LFA1/{print a[NR-2];print $0}' f                                                                                        
Tue Jul  2 08:42:16 2013 +02:00
ACTION :[68] 'update SAPPRD.USR02 set uflag=64 where BNAME='CANAS' and MANDT='000''
于 2013-07-30T22:31:16.283 回答
0

你为什么不这样做呢?

grep -Ei "USR02|USH02|TCURR|REGUH|LFB1|LFA1" -B 2 file

grep -e承认多个参数。所以代替grep -i ONE然后grep -i TWO,你可以这样做grep -Ei "ONE|TWO"

-B 2您所做的是打印匹配行的前两行。

测试

所有这些将构成以下内容:

$ grep -Ei "USR02|USH02|TCURR|REGUH|LFB1|LFA1" -B 2 file
Tue Jul  2 08:42:16 2013 +02:00
LENGTH : '222'
ACTION :[68] 'update SAPPRD.USR02 set uflag=64 where BNAME='CANAS' and MANDT='000''

如果你不想要中间的那条线,

$ grep -Ei "USR02|USH02|TCURR|REGUH|LFB1|LFA1" -B 2 file | grep -v LENGTH
Tue Jul  2 08:42:16 2013 +02:00
ACTION :[68] 'update SAPPRD.USR02 set uflag=64 where BNAME='CANAS' and MANDT='000'
于 2013-07-02T14:22:09.850 回答