2018-02-08

Filtering and Splitting Lines With AWK & "while read"


In this example lines contained in a ksh/bash String are:
  • filtered (by awk)
  • duplicate consecutive lines are removed (by awk)
  • then split only using the shell internal "while read" feature (without needing to use "cut, awk"  or other external "binaries")

Example: if ${RESULT_STR} (see below) contains:
*********************** Backup Status of DB_29384_SITE1 ************************
Backup Type   Status                   Start Time       Error Message
------------- ------------------------ ---------------- ---------------------------
ARCHIVELOG    COMPLETED                2018.02.07 16:54 
ARCHIVELOG    COMPLETED WITH WARNINGS  2018.02.07 17:00 RMAN-08137: WARNING: ...
ARCHIVELOG    COMPLETED                2018.02.07 20:55 
ARCHIVELOG    COMPLETED WITH WARNINGS  2018.02.07 21:06 RMAN-08137: WARNING: ...
DB INCR       COMPLETED                2018.02.08 02:00  ARCHIVELOG    COMPLETED                2018.02.08 03:04 
DB INCR       COMPLETED                2018.02.08 03:06 
ARCHIVELOG    COMPLETED WITH WARNINGS  2018.02.08 03:53 RMAN-08137: WARNING: ...
ARCHIVELOG    COMPLETED                2018.02.08 04:54 

AWK: Filtering & Removing Duplicate Lines
The result of
print - "${RESULT_STR}" | 
  awk '/ RMAN-| ORA-/
    MSG=substr($0, 86)
    if(MSG!=PREV){ 
      print MSG
      PREV=MSG 
    }
  }' 
is:
("/ RMAN-| ORA-/" filters the "interesting" lines – containing error/warning messages. "substr($0, 86)" returns the end of the string starting with column 57. "MSG and PREV" are used in order to remove duplicate consecutive lines)
RMAN-08137: WARNING: archived log not deleted, needed for standby or upstream capture process 

While Read: Splitting The Input
"errNr" gets the characters up to the first space, "errTxt" receives all other characters until the end of line
print - "${RESULT_STR}" | 
  awk '/ RMAN-| ORA-/{
    MSG=substr($0, 57)
    if(MSG!=PREV){ 
      print MSG
       PREV=MSG
   }
  }' |
  while read errNr errTxt ; do
    print - "errNr: ${errNr} / errTxt: ${errTxt} "
  done
Output
errNr: RMAN-08137: / errTxt: WARNING: archived log not deleted, needed for standby or upstream capture process 

Specifying a "while read" Delimiter
The delimiter can be changed from space to colon by using "IFS=':'"
IFS=':'
print - "${RESULT_STR}" |
  awk '/ RMAN-| ORA-/{MSG=substr($0, 57); if(MSG!=PREV){ print MSG; PREV=MSG }}' |
  while read errNr errTxt ; do
    print - "errNr: ${errNr} / errTxt: ${errTxt} "
  done
Output (without ':' after RMAN-08137)
errNr: RMAN-08137 / errTxt: WARNING: archived log not deleted, needed for standby or upstream capture process

[]

No comments :

Post a Comment