shell - usar - AIX: utilizando el comando grep para registrar dos líneas de un archivo
usar grep (3)
Entradas de auditoría básicamente .aud
almacenadas como archivos .aud
en mi sistema AIX
/oracle/SBX/saptrace/audit/
Las entradas de estos archivos se ven así:
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''
Ahora tengo un cronograma de shell en crontab para que se ejecute cada tres horas.
Script es algo como esto:
#/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
Lo que hace este script es si hay alguna operación en estas tablas, esa línea se registra en /EDB/log/check_audit_dest.log
Me gusta esto:
# 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''''
Ahora lo que quiero es aparte de esa línea, también quiero que la primera línea de cada entrada sea iniciar sesión en ese archivo de registro (por ejemplo: Tue Jul 2 08:42:16 2013 +02:00
).
Gracias
¿Por qué no lo haces así?
grep -Ei "USR02|USH02|TCURR|REGUH|LFB1|LFA1" -B 2 file
grep -e
admite múltiples parámetros. Entonces, en lugar de grep -i ONE
y grep -i TWO
, puedes hacer grep -Ei "ONE|TWO"
.
Con -B 2
lo que debes hacer es imprimir las dos líneas anteriores de la línea coincidente.
Prueba
Todos juntos harán lo siguiente:
$ 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''''
y si no quieres la línea en el medio,
$ 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''
Ed Morton dio una solución awk con configuración de RS
y FS
. Aquí hay otra solución con awk:
awk ''!$0{delete a;next}{a[NR]=$0}/USR02|USH02|TCURR|REGUH|LFB1|LFA1/{print a[NR-2];print $0}'' file
la primera parte !$0{delete a;next}
podría eliminarse si tu archivo no es un gran monstruo:
awk ''{a[NR]=$0}/USR02|USH02|TCURR|REGUH|LFB1|LFA1/{print a[NR-2];print $0}'' file
salida con su entrada:
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''''
Dado el aporte de muestra que publicó, todo lo que necesita es:
$ 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''''
Si eso no funciona, publique algunos datos más representativos y resultados esperados.
Explicación según lo solicitado abajo por fedorqui
-
RS=
=> los registros están separados por líneas en blanco -
-F''/n''
=> campos dentro de un registro están separados por líneas nuevas -
/USR02|USH02|TCURR|REGUH|LFB1|LFA1/
=> buscar registros que contengan cualquiera de|
-cadenas separadas -
print FILENAME, $1, $3
=> imprimir el nombre del archivo actual, y la 1ª y 3ª líneas / campos del registro actual, la 1ª línea es la fecha y el 3º es la ACCIÓN.