2

I was reviewing one bash script and am stuck despite my googling efforts to decipher as to how this particular function works.

I got the part for gettimestamp & printeverything works and how it is called. However starting with ORA up until Housetype I am not sure how it works. According to this AWK tutorial there are predefined functions within AWK and it always starts with function but I couldn't see any reference or examples for the code that is enclosed in "<---Section is confusing---->". I am not asking for anyone to explain the whole code but in particular if you can explain at least how /^DocType\|/ works section. Please see my comments below.

    func_sql()
    {
            ITMF=$TMF.2
            _retrieve | _run_sqlplus 2>&1 | ${_APP_AWK} -vtmf=$ITMF '

            BEGIN {
                    FS = "^B";
                    cnt=0;
                    printf("umask 007;\n") >>tmf
                    printf("cd %s;\n", imgDir) >>tmf
            }

            function getTimeStamp(s) {
                    printf("%s %s\n", strftime("[%a %b %d %H:%M:%S]"), s) >>logFile
            }

            function printEverything(s) {
                    printf("<P>%s %s\n", strftime("[%a %b %d %H:%M:%S]"), s);
                    printf("%s %s\n",
                            strftime("[%a %b %d %H:%M:%S]"),
                            s) >>logFile
            }
    <--- This section is confusing ------>
            /^ORA-.*:|^PLS-.*:|^SP2-.*/ { <-- I don't understand this part
                    getTimeStamp($0) <--- I understand this
                    printf("\nSQLBAD|1000|%s\n", $0); <--- I understand this
                    exit(1); <--- I understand this
            }

            /^ERROR/ { <-- I don't understand this part
<--Truncated-->
            }

            /\[.*\]\|Error.*/ { <-- I don't understand this part
                    <--Truncated-->
            }

            /^HouseType\|/ { <-- I don't understand this part
                    gsub("[[:space:]]+", " ");<--- I understand this
                    gsub("^[[:space:]]+", "");<--- I understand this
                    gsub("[[:space:]]+$", "");<--- I understand this
                    gsub("[[:space:]]+^B", "^B");<--- I dont' know this bit, what does ^B stands for?
                    gsub("^B[[:space:]]+", "^B");<--- I dont' know this bit, what does ^B stands for?

                    if($0 == "")
                            next;

                    print "<option value=\"" $2 "\">" $3 "</option>";

                    next;
            }
            {
                    gsub("[[:space:]]+", " ");
                    gsub("^[[:space:]]+", "");
                    gsub("[[:space:]]+$", "");

                    if($0 == "")
                            next;
            }
    <--- This section is confusing ------>    
            END {
                    printf("cnt=%s\n", cnt);
            }
            '

1 Answer 1

8

It seems like you're saying that part of what you don't understand is the regular expression trigger syntax of awk, which is that from which it derives a lot of its power. To simplify, the scaffolding of an awk script can be described thusly:

BEGIN {
    Things to do before processing data
}

/needle/  {
    Things to do when a record contains a match for the regex /needle/
}

expression {
    Things to do for each record when the expression evaluates to true (i. e. nonzero)
}

{
    Things to do for all input records
}

END {
    Things to do after all records have been processed
}

To expand on this for the lines you reference:

/^ORA-.*:|^PLS-.*:|^SP2-.*/ {
    stuff
}

/^ORA-.*:|^PLS-.*:|^SP2-.*/ is a regular expression that matches any string matching any of the following criteria:

  • Starts with ORA-, with a : following zero or more subsequent characters
  • Starts with PLA-, with a : following zero or more subsequent characters
  • Starts with SP2-

The code in the curly braces following that expression will be run upon any record which matches.

/^ERROR/ {
    stuff
}

A simpler regular expression which matches any string starting with ERROR.

/\[.*\]\|Error.*/ {
    stuff
}

Another regex, this time matching a string starting with anything with a matched pair of square braces, or anything with the string Error.

gsub("[[:space:]]+^B", "^B");
gsub("^B[[:space:]]+", "^B");

These will replace any series of characters matching whitespace followed by a Ctrl+B character in the first case, or the reverse order in the second, with a simple Ctrl+B. Keep in mind that that control character was defined in the BEGIN stanza as the field separator.

3
  • thanks for taking the time to explain the code, the "scaffolding" part. I just have a few clarification for example in this part "/^ORA-.*:|^PLS-.*:|^SP2-.*/" as you have stated it is a regex. If I understand correctly it will match a string given the regex pattern. Since there is a pipe in between ORA, PLS and SP2 does it mean that it needs to match first ORA regex pattern then pipe it to PLS etc. Or given a string it will match all the regex expression?
    – dimas
    Mar 28, 2017 at 5:52
  • | here means "or", it's not related to shell pipes. Mar 28, 2017 at 6:20
  • 4
    @dimas Some ~25 years ago I learned awk in two days, reading the man page of mawk. I highly recommend it: it's very well written, and probably still the most concise reference available. Mar 28, 2017 at 10:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .