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);
            }
            '
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 '17 at 5:52
  • | here means "or", it's not related to shell pipes. Mar 28 '17 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 '17 at 10:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.