INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Jobs

Using ANSI with Awk

How can I introduce colour into the output of my Awk scripts by menski
Posted: 21 Dec 02 (Edited 27 Dec 02)

ANSI code has always been pretty much of a minority interest and
(slightly old fashioned) black art, but it is useful & can be
very effective in conjunction with Awk.  This FAQ just covers the
graphics parameters that allow coloured text, reverse video etc -
it does not cover the parameters which control the cursor movement
and on screen placement.

ANSI graphics parameters take the form

    ESC[att;attm

where 'ESC' is the escape, 'att' represents one or more attributes
separated by ';' and 'm' terminates the code.  In Linux (Unix) the
escape is \033, so:

    echo -e '\033[5;41;1;37m    *** STOP ***    \033[0m'

will print the flashing message '    *** STOP ***    ' in bright white
letters on a red background.  The instruction '\033[0m' turns off all
attributes and returns the screen to its normal appearance.

A nice feature is that ANSI code is recognized by LESS.  ie:
Piping the output of the sample script provided with this FAQ
thru' LESS with either the -r or -R option set:

    awk -f awkdir | less -R

will give you the output in colour & with the various LESS functions
available.

There are 8 background colours and the use of the bold attribute provides
16 foreground (the old CGA colour set).  The 'concealed on' attribute can
be used to hide input for passwords etc.

Foreground            Background
   30 - black      34 - blue            40 - black    44 - blue
   31 - red        35 - magenta       41 - red      45 - magenta
   32 - green    36 - cyan             42 - green    46 - cyan
   33 - yellow   37 - white            43 - yellow   47 - white

   0 - all attributes off
   1 - bold (bright) on
   2 - faint on (bold off)
   5 - blink on
   7 - reverse video
   8 - concealed on

The script I've used here to demonstrate the use of ANSI with Awk, runs
'ls -AlF' thru' getline & produces a report at the end (a la DOS) giving
the total size of the directory, number of files etc.  The report is
printed in bright white on white (or gray).  The directory meanwhile
retains its 'colourized' form with executables printed in bright green,
directories in bright blue, links in yellow & (as an added bonus) backup
files in bright magenta.  The colourization, of course, would normally be
lost in the process of running the data thru' Awk - and the backup files
would only ever be identified by the trailing tilde (~).

# = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - =

# awkdir (Tek-Tips ANSI example for use w. Awk: dmk 12/02)

BEGIN {

    while (("ls -AlF" | getline) > 0) {
        print crap_sort($0)
        dsz = (dsz + $5)
        dcnt++
        }
    close("ls -AlF")
    exit
    } # Close: BEGIN


END {
# set various
    on = "\033[47;1;37m";    off = "\033[0m\n"
    spc1 = "%-19s";        sep1 = "%2s"
    spc2 = "%4s";        sep2 = "%3s"
    spc3 = "%10s";        sep3 = "%6s"
    spc4 = "%6s";        sep4 = "%3s"

    for (i = 1; i <= 4; i++) rprt_wrtr(i)

    } # Close: END

# FUNCTIONS----------------------------------------------------

 function crap_sort(input_str,  ftype) {
    
    if (input_str ~ /\/$/ || # find char at end of string
        input_str ~ /*$/ ||
            input_str ~ /@$/ ||
                input_str ~ /\~$/ ||
                    $10 == "->") {

        ftype = substr(input_str,length()) # picks-up last char
        input_str = substr($0,1,56) # picks-up 1st eight fields

# sets directory to bright blue
        if (ftype == "/") {
            input_str = input_str "\033[1;34m"\
                substr($9, 1, (length($9)-1))"\033[0m"
            sdcnt++
            sdsz = (sdsz + $5)
            }

# sets command to bright green
        else if (ftype == "*") {
            input_str = input_str "\033[1;32m"\
                substr($9, 1, (length($9)-1))"\033[0m"
            }

# sets link to yellow
        else if (ftype == "@") {
            input_str = input_str "\033[33m"\
                substr($9, 1, (length($9)-1))"\033[0m"
            }

# sets backup to bright magenta
        else if (ftype == "~") {
            input_str = input_str "\033[1;35m"\
                substr($9, 1, (length($9)-1))"\033[0m"
            }

# sets link in form 'termcap -> /usr/share/misc/termcap' to yellow
        else {
            input_str = input_str "\033[33m"\
                substr($9, 1, length($9))\
                        "\033[0m "$10" "$11
            }
        }

        return input_str

    } # ----------Close: function crap_sort()


 function rprt_wrtr(i,  msg) {

# This function writes the report using bright white on gray
# (white) background.

# TIP----------------------------------------------------------

# NB When using printf() (or sprintf()) set attribs separately
# from the formatting eg:

#    printf("  \033[47;1;37m"); printf("%-19s", "No. of files")

# This example:

#       printf("%-20s","  \033[47;1;37mNo. of files"

# does not work well (concatenates the expression, the
# formatting is lost).

# Examples of this are shown at 'else if (i == 3) {' (below)
# & also (although less obviously) in the construct:

#     printf("  "on)
#    printf(spc1, msg[1])

# at the head of the message writing block (below).

# END of TIP---------------------------------------------------

    if (i == 1) {
        msg[1] = " No. of files"
        msg[2] = (dcnt - sdcnt) # all in dir less sub-dirs
        msg[3] = (dsz - sdsz) # all size less sub-dir size
        }
    else if (i == 2) {
        msg[1] = " No. of directories"
        msg[2] = sdcnt # no. of sub-dirs
        msg[3] = sdsz # their size
        }
    else if (i == 3) {
# sets separator line to bright black: see also TIP (above)
        msg[1] = sprintf("\033[1;30m")
        msg[1] = sprintf("%19s","-------")
        msg[2] = "--"
        msg[3] = "----"
        msg[4] = "---"
        }
    else {
        msg[1] = " Total"
        msg[2] = (dcnt) # all in directory
        msg[3] = (dsz) # size
        }

# see also TIP (above) - either
#    printf("  \033[47;1;37m")
# or
    printf("  "on) # see 'set various' (above)

    printf(spc1, msg[1])
    if (i != 3) {
        printf(sep1,": ")

        msg[4] = int(msg[3]/1024) # byte to kbyte
        if ((msg[3] % 1024) > 512) msg[4]++ # round-up

        printf(spc2, thousep(msg[2]));    printf(sep2,"- ")
        printf(spc3, thousep(msg[3]));    printf(sep3,"byt: ")
        printf(spc4, thousep(msg[4]));    printf(sep4,"K ")
        }
    else { # line 3: broken line separator
        printf("  ")
        printf(spc2, msg[2]);    printf(sep2," ")
        printf(spc3, msg[3]);    printf(sep3," ")
        printf(spc4, msg[4]);    printf(sep4," ")
        }
    printf(off) # see comment (above)

    return 1

    } # ----------Close: function rprt_wrtr()


 function thousep(num,  nlngth, numWsep) {

    numWsep = 0
    nlngth = length(num)
    while (nlngth > 3) {
        numWsep != 0 ?
            numWsep = substr(num, (nlngth-2), 3)","numWsep :
                      numWsep = substr(num, (nlngth-2), 3)
        nlngth = (nlngth - 3)
        }

    if (nlngth > 0) {
        numWsep != 0 ?
            numWsep = substr(dsz, 1, nlngth)"," numWsep :
                            numWsep = num
        }

    return numWs# = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - =

 

Back to AWK FAQ Index
Back to AWK Forum

My Archive

Resources

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close