AIX:使用grep命令记录文件中的两行

时间:2013-07-02 13:27:09

标签: shell logging awk grep aix

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

/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)。

谢谢

3 个答案:

答案 0 :(得分:4)

根据您发布的样本输入,您只需要:

$ 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行,第1行是日期,第3行是行动。

答案 1 :(得分:2)

Ed Morton提供了设置RSFS的awk解决方案。 这是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''

答案 2 :(得分: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'