Can you please explain as to how the followin piece of code works?


l_THIS_FILE=`echo $l_Basename | awk -F. '{field=1
             while (field < NF) {
                 printf $field
                 if (field < NF - 1) {
                     printf "."}
             printf "\n"}'`

-F. sets the Field Separator to .: Given a line a.b.c., awk will see four fields: a, b, c, and (an empty field).

while (field < NF) 
     printf $field
     if (field < NF - 1) 
         printf "."
  • The code loops over each field and prints it. Note that field begins with 1, as field 0 is the entire line (or record, to be precise). Since the check is < NF, it never reaches the last field.
  • Until the second-last field, it adds a ., presumably as a field separator for some other program to handle.

All told this code is a convoluted way of implementing basename, a command often used to strip the extension from a filename:

$ basename hello_world.ksh .ksh

Even in awk, a more concise way would be to decrement the number of fields by one: NF--, and set the Output Field Separator to ., so that it gets automatically added between fields:

$ echo hello_world.ksh | awk -F. -v OFS=. '{NF--}1'

The "-F" option allows changing Awk's "field separator" character. Awk regards each line of input data as composed of multiple "fields", which are essentially words separated by blank spaces. A blank space (or a tab character) is the default "field separator". In some cases, the input data may be divided by another character, for example, a ":", and it would be nice to be able to tell Awk to use a different field separator. This is what the "-F" option does. To invoke Awk and specify a ":" as the field separator, we write:

awk -F: ...

In this case, the field separator is a "."

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.