Search code examples
awksedsolaris

sed not consistently stripping blocks from log file


There is a log file generated by Oracle RMAN that I'd like to pass through with sed and strip out positive validation results.

The original log file can be viewed here: https://pastebin.com/XhEEs9e9

This log file consists of many sections like this:
File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
58   OK     0              7964         1280000         8964120502
  File Name: /oracle/PRD/sapdata3/sr3_55/sr3.data55
  Block Type Blocks Failing Blocks Processed
  ---------- -------------- ----------------
  Data       0              322650          
  Index      0              232975          
  Other      0              716411          

What I am trying to achieve is to have sed strip out the blocks where all the corrupt blocks and failing blocks are '0'.

To accomplish this, I have crafted out a rather long sed command like so:

/tmp/rman.log | /usr/gnu/bin/sed -E '/^File[[:space:]]*Status[[:space:]]*Marked[[:space:]]*Corrupt[[:space:]]*Empty[[:space:]]*Blocks[[:space:]]*Blocks[[:space:]]*Examined[[:space:]]*High SCN$/{N;N;/\n[[:digit:]]*[[:space:]]*OK[[:space:]]*[[:digit:]]*[[:space:]]*[[:digit:]]*[[:space:]]*[[:digit:]]*[[:space:]]*[[:digit:]]*$/{N;N;N;N;/\n[[:space:]]*Data[[:space:]]*0[[:space:]]*[[:digit:]]*[[:space:]]*$/{N;/\n[[:space:]]*Index[[:space:]]*0[[:space:]]*[[:digit:]]*[[:space:]]*$/{N;/\n[[:space:]]*Other[[:space:]]*0[[:space:]]*[[:digit:]]*[[:space:]]*$/d}}}}'

The command appeared to work, some of the blocks are stripped out from the original log file, however some of the blocks are left behind.

The problem is, I can't tell why... :(

The filtered log can be seen here: https://pastebin.com/rKgfj28B

Am I missing something with my command? The ones left behind have "0"s for corrupt blocks and failing blocks too, but somehow they just don't match.


Solution

  • If that block of text starting with File in your question is a "block" and there are blank lines between each block, e.g.:

    $ cat file
    File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
    ---- ------ -------------- ------------ --------------- ----------
    58   OK     3              7964         1280000         8964120502
      File Name: /oracle/PRD/sapdata3/sr3_55/sr3.data55
      Block Type Blocks Failing Blocks Processed
      ---------- -------------- ----------------
      Data       0              322650
      Index      0              232975
      Other      0              716411
    
    File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
    ---- ------ -------------- ------------ --------------- ----------
    58   OK     0              7964         1280000         8964120502
      File Name: /oracle/PRD/sapdata3/sr3_55/sr3.data55
      Block Type Blocks Failing Blocks Processed
      ---------- -------------- ----------------
      Data       0              322650
      Index      0              232975
      Other      0              716411
    
    File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
    ---- ------ -------------- ------------ --------------- ----------
    58   OK     0              7964         1280000         8964120502
      File Name: /oracle/PRD/sapdata3/sr3_55/sr3.data55
      Block Type Blocks Failing Blocks Processed
      ---------- -------------- ----------------
      Data       0              322650
      Index      1              232975
      Other      0              716411
    

    then this is all you need:

    $ awk -v RS= -v ORS='\n\n' '($19 $36 $39 $42)+0' file
    File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
    ---- ------ -------------- ------------ --------------- ----------
    58   OK     3              7964         1280000         8964120502
      File Name: /oracle/PRD/sapdata3/sr3_55/sr3.data55
      Block Type Blocks Failing Blocks Processed
      ---------- -------------- ----------------
      Data       0              322650
      Index      0              232975
      Other      0              716411
    
    File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
    ---- ------ -------------- ------------ --------------- ----------
    58   OK     0              7964         1280000         8964120502
      File Name: /oracle/PRD/sapdata3/sr3_55/sr3.data55
      Block Type Blocks Failing Blocks Processed
      ---------- -------------- ----------------
      Data       0              322650
      Index      1              232975
      Other      0              716411
    

    otherwise if there aren't blank lines between the blocks then this is all you need:

    $ cat tst.awk
    /^File/ { if (NR>1) prt() }
    { rec = rec $0 ORS }
    END { prt() }
    
    function prt(   f) {
        split(rec,f)
        if ( (f[19] f[36] f[39] f[42])+0 ) {
            printf "%s", rec
        }
        rec = ""
    }
    

    For example:

    $ cat file
    File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
    ---- ------ -------------- ------------ --------------- ----------
    58   OK     3              7964         1280000         8964120502
      File Name: /oracle/PRD/sapdata3/sr3_55/sr3.data55
      Block Type Blocks Failing Blocks Processed
      ---------- -------------- ----------------
      Data       0              322650
      Index      0              232975
      Other      0              716411
    File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
    ---- ------ -------------- ------------ --------------- ----------
    58   OK     0              7964         1280000         8964120502
      File Name: /oracle/PRD/sapdata3/sr3_55/sr3.data55
      Block Type Blocks Failing Blocks Processed
      ---------- -------------- ----------------
      Data       0              322650
      Index      0              232975
      Other      0              716411
    File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
    ---- ------ -------------- ------------ --------------- ----------
    58   OK     0              7964         1280000         8964120502
      File Name: /oracle/PRD/sapdata3/sr3_55/sr3.data55
      Block Type Blocks Failing Blocks Processed
      ---------- -------------- ----------------
      Data       0              322650
      Index      1              232975
      Other      0              716411
    

    .

    $ cat tst.awk
    /^File/ { if (NR>1) prt() }
    { rec = rec $0 ORS }
    END { prt() }
    
    function prt(   f) {
        split(rec,f)
        if ( (f[19] f[36] f[39] f[42])+0 ) {
            printf "%s", rec
        }
        rec = ""
    }
    

    .

    $ awk -f tst.awk file
    File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
    ---- ------ -------------- ------------ --------------- ----------
    58   OK     3              7964         1280000         8964120502
      File Name: /oracle/PRD/sapdata3/sr3_55/sr3.data55
      Block Type Blocks Failing Blocks Processed
      ---------- -------------- ----------------
      Data       0              322650
      Index      0              232975
      Other      0              716411
    File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
    ---- ------ -------------- ------------ --------------- ----------
    58   OK     0              7964         1280000         8964120502
      File Name: /oracle/PRD/sapdata3/sr3_55/sr3.data55
      Block Type Blocks Failing Blocks Processed
      ---------- -------------- ----------------
      Data       0              322650
      Index      1              232975
      Other      0              716411