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 ...
- 10-17-2009 #1Just 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
I would know what are the following commands doing. The first one prints all /etc/passwd, second prints nothing.Code:awk 'BEGIN { FS = ":"} {if ($1 == "root") print $6 }' /etc/passwd
Code:awk 'FS = ":"; {if ($1 == "root") print $6 }' /etc/passwdWhat 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.Code:awk '{FS = ":"; if ($1 == "root") print $6 }' /etc/passwd
also this command work as expected but it is just different form of first
Thanks a lotCode:awk -F ':' '{if ($1 == "root") print $6 }' /etc/passwd
- 10-17-2009 #2Linux 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
- 10-18-2009 #3Just 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 ';' ?
- 10-18-2009 #4Linux Newbie
- Join Date
- Jan 2008
- Location
- Canada
- Posts
- 109
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.awk 'BEGIN { FS = ":";x=0} {if ($1 == "root") print $6 }' /etc/passwd
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
- 10-20-2009 #5Just 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 ?
- 10-21-2009 #6Linux Newbie
- Join Date
- Jan 2008
- Location
- Canada
- Posts
- 109
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


Reply With Quote
