Find the answer to your Linux question:
Results 1 to 6 of 6
Hi I am trying to understand AWK syntax so I tried this command which gives me the home directory of root Code: awk 'BEGIN { FS = ":"} {if ($1 ...
  1. #1
    Just Joined!
    Join Date
    Jul 2009
    Posts
    49

    AWK syntax

    Hi I am trying to understand AWK syntax
    so I tried this command which gives me the home directory of root

    Code:
    awk 'BEGIN { FS = ":"} {if ($1 == "root") print $6 }' /etc/passwd
    I would know what are the following commands doing. The first one prints all /etc/passwd, second prints nothing.

    Code:
    awk 'FS = ":"; {if ($1 == "root") print $6 }' /etc/passwd
    Code:
    awk '{FS = ":"; if ($1 == "root") print $6 }' /etc/passwd
    What are the differences between those three commands? I know about awk that in BEGIN I put code that is executed once before processing rows. and END is executing at the end of processing all rows.


    also this command work as expected but it is just different form of first
    Code:
    awk -F ':' '{if ($1 == "root") print $6 }' /etc/passwd
    Thanks a lot

  2. #2
    Linux Newbie
    Join Date
    Jan 2008
    Location
    Canada
    Posts
    109
    Hi wakatana
    The first invocation is a classic way of calling 'awk' . It is syntactically correct and hence gives a reliable result.
    Remember the use of ';' essentially terminates a command ( as it does in shell scripts as well). Hence in the second invocation the ';' terminates the command and the enclosure portion never gets parsed. Because the parser is satisfied at each line of /etc/passwd it simply prints it out as it receives it and the conditional is never performed.
    The third invocation is terminated on each line at the ';' and never prints the line because it never gets to the second part of the command. Remember the {} are the eclosure for any single command per line until a end of line condition arises, again at the ';'. This invocation is not a good one even without the ';' as it sets the FS at every line parsed. This is very inefficient and poor coding style. Hence because of the ';' no output.
    The last one, which is possibly the most parsimonious of the invocations (because it sets the field separator only once) gives consistently good results ( and uses less caharcters than the first one of you invocations).
    In short use the ';' with caution or not at all. Cheers...
    Robert

  3. #3
    Just Joined!
    Join Date
    Jul 2009
    Posts
    49
    But if I have multiple variables i have to use ';' If I understand correnct I have to declare variables in BEGIN block and ';' symbol ending awk syntax and did not execute command after ';' ?

  4. #4
    Linux Newbie
    Join Date
    Jan 2008
    Location
    Canada
    Posts
    109
    awk 'BEGIN { FS = ":";x=0} {if ($1 == "root") print $6 }' /etc/passwd
    The above ';' will work but only as a separator NOT at the end of the assignments. ie. Not required just before the <} {if> conditional. If you are writing callable scripts, an end of line works as well.
    BEGIN {
    FS=":"
    x=0
    }
    If only one assignment is made in a BEGIN statement no ';' is required. If more than one are required you need n-1 ';' but not after the last assignment.
    I was unable to get the last invocation to accept more than one assignment using the awk -F ':' approach. I usually write my scripts and call them using awk -f. I have never tried to enter them at the command line so my experience is limited in this latter approach. Not sure this helps that much but hope you get your problem resolved. Cheers...
    Robert

  5. #5
    Just Joined!
    Join Date
    Jul 2009
    Posts
    49
    Thanks for reply,
    so in conclusion awk syntax should looks like:

    awk BEGIN {declaration of variables if I want use some} {actions, or declarations of variables that will change during execution} END{if I want some summary etc}

    or am i wrong ?

  6. #6
    Linux Newbie
    Join Date
    Jan 2008
    Location
    Canada
    Posts
    109
    Quote Originally Posted by wakatana View Post
    Thanks for reply,
    so in conclusion awk syntax should looks like:

    awk BEGIN {declaration of variables if I want use some} {actions, or declarations of variables that will change during execution} END{if I want some summary etc}

    or am i wrong ?
    Hi wakatana
    Essentially what you say is correct. Awk is a language, which like so many others, has evolved over the years. It is somewhat dependant on your particular implementation but they all do much the same thing. Syntax can be a bit different depending if you have a traditional awk or a more modern awk implementation, which could be POSIX compliant.
    Essentally you can print out information within the BEGIN section, maybe a header or something BUT it only handles one instance (could have many lines printed but once it leaves the BEGIN section it is out and never returns). It could have a do loop or something which could print many lines to output, usually fixed information (headers). Similarly with end.
    No lines are read from the input file (or standard input) until the program advances from the BEGIN section. Generally <tests> and <actions> fall in the main section of the code. The program goes to the end of any file being processed (or hits an exit which sends it immediately to the END section (if on exists). Otherwise it continues to read every line in the file being processed until it comes to the end of the file.
    In the END section one can Print Summaries and possibly Numeric Totals or whatever and then the Script is closed.

    The following invocation works on my system and might show you a function that uses all parts BEGIN, END and a Test Section (Main Program). I created a <List> text file which has three entries in it (also shown below). Put this in the same directory you will run the Terminal from.

    File <List> follows: Just copy the next three lines into a text editor and name it <List>
    fuuu
    nofu
    follow

    The first 4 lines of the following section should be copied one line at a time to a Command Line on your machine followed by a <return>

    awk '
    BEGIN { print "Analysis of \"fu\"" }
    /fu/ { ++n }
    END { print "\"fu\" appears", n, "times." }' List

    The following is the output when I ran this program:

    -| Analysis of "fu"
    My Comments-----> This is line one of Output Printed from BEGIN section.
    -| "fu" appears 2 times.
    My Comments-----> This is line 2 of output Printed from the END section.



    awk 'BEGIN { print "Analysis of \"fu\"";x=100;z=200 } /fu/ { ++n }END { print "\"fu\" appears", n, "times.","\n","x equals",x,"z equals",z}' List

    My Comments-----> The above invocation also works.
    Since x and z are only assigned once, you want them to be in BEGIN and not main body of program where they would be reassigned every time a line is read.
    I know how long and detailed this is but I remember when I first started using <awk> and how frustrating things can become. Cheers...
    Robert

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...