Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game. |
| Notices |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
 |
GNU/Linux Basic Guide
This 255-page guide will provide you with the keys to understand the philosophy of free software, teach you how to use and handle it, and give you the tools required to move easily in the world of GNU/Linux. Many users and administrators will be taking their first steps with this GNU/Linux Basic guide and it will show you how to approach and solve the problems you encounter.
Click Here to receive this Complete Guide absolutely free. |
|
 |
10-17-2009, 10:50 AM
|
#1
|
|
Member
Registered: Jul 2009
Location: Slovakia
Posts: 133
Rep:
|
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
|
|
|
|
10-17-2009, 03:54 PM
|
#2
|
|
Senior Member
Registered: Oct 2003
Location: Northeastern Michigan, where Carhartt is a Designer Label
Distribution: Slackware 32- & 64-bit Stable
Posts: 2,504
|
When you set an AWK variable (FS is a predefined variable and you're resetting it to a new value), you really need to do that in the BEGIN section; that way, it stays in effect throughout the program execution.
Just the way it's done.
|
|
|
|
10-18-2009, 09:52 AM
|
#3
|
|
Member
Registered: Jul 2009
Location: Slovakia
Posts: 133
Original Poster
Rep:
|
And is there ways if is variable declared not in BEGIN ? or it is just my mistake ? i think it is syntacticaly correct because awk did not report syntax error.
|
|
|
|
10-18-2009, 11:34 AM
|
#4
|
|
LQ 5k Club
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian Squeeze (server), Slackware 13.37 (netbook), Slackware64 14.0 (desktop),
Posts: 8,367
|
Hello wakatana
The awksperts haven't rushed to answer so you'll have to make do with me, more of an awkateur.
Quote:
Originally Posted by wakatana
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?
|
Awk programs are composed of patterns and actions. Actions are enclosed in braces, { }. If the action is omitted the default action of printing the entire line is assumed.
In
Code:
awk 'FS = ":"; {if ($1 == "root") print $6 }' /etc/passwd
there are two pattern-action pairs separated by the ;. The first pattern, intended as (and effective as) an assignment somehow matches all lines (I cant figure out why) and is not followed by an action so the default action is taken. These variations are instructive
Code:
c:~$ awk 'FS = ":"' /etc/passwd
[prints the whole file]
c:~$ awk 'FS = ":" {print $1}' /etc/passwd
[shows the assignment is effective but not for the first line]
In
Code:
awk '{FS = ":"; if ($1 == "root") print $6 }' /etc/passwd
there is no pattern so the action is taken for every line. The FS assignment is not effective for the first line so $1 is the entire line and the match fails as it does for every subsequent line because the root line is the first line. This variation is instructive
Code:
c:~$ awk '{FS = ":"; if ($1 == "bin") print $6 }' /etc/passwd
|
|
|
|
10-18-2009, 04:01 PM
|
#5
|
|
Member
Registered: Jul 2009
Location: Slovakia
Posts: 133
Original Poster
Rep:
|
Thanks catkin for your reply. It is clearer.
I understand it that way
Code:
awk 'FS = "SOMETHING_WEIRD"; {if ($1 == "root") print $6666 }' /etc/passwd
Always will be printed whole file because I have not action before ';' so it execute default action print. And it never goes to second action (after ';') (I dont know why???)
Code:
awk 'FS = ":" {print $1}' /etc/passwd
sets the separator after proceeding first line because of missing BEGIN keyword (for that reason it would not print first line just the others)
Code:
awk '{FS = ":"; if ($1 == "root") print $6 }' /etc/passwd
awk '{FS = ":"; if ($1 == "bin") print $6 }' /etc/passwd
Is still unclear for me. If i made some mistakes please correct me
|
|
|
|
10-18-2009, 05:04 PM
|
#6
|
|
Senior Member
Registered: Oct 2003
Location: Northeastern Michigan, where Carhartt is a Designer Label
Distribution: Slackware 32- & 64-bit Stable
Posts: 2,504
|
According to Alfred V. Aho, Brian W. Kernighan, Peter J. Weinberger The AWK Programming Language (New York: Addison-Wesley Publishing Co., 1988, ISBN 0-201-07981X), the syntactic rules for the command line (p. 187) include
Quote:
awk [-Fs] 'program' optional list of filenames
awk [-Fs] -f progrfile optional list of filenames
|
that is, an assignment to the FS built-in variable is outside the program.
and p. 23
Quote:
|
The BEGIN and END patterns do not mathc any input rules do not match any input lines. Rather, the statements in the BEGIN action are executed before awk reads any input; the statements in the END action are executed after all input has been read. BEGIN and END thus provide a way to gain control for initialization and wrap up.
|
Hope this helps some.
|
|
|
|
10-20-2009, 05:35 AM
|
#7
|
|
Member
Registered: Jul 2009
Location: Slovakia
Posts: 133
Original Poster
Rep:
|
So in concusion declaring variables should be done in BEGIN block ? Or Am I wrong ?
|
|
|
|
10-20-2009, 06:21 AM
|
#8
|
|
Senior Member
Registered: Oct 2003
Location: Northeastern Michigan, where Carhartt is a Designer Label
Distribution: Slackware 32- & 64-bit Stable
Posts: 2,504
|
Quote:
Originally Posted by wakatana
So in concusion declaring variables should be done in BEGIN block ? Or Am I wrong ?
|
Yes, declaring variables is best done in a BEGIN.
If you intend to do a lot of programming in AWK I'd recommend that you find a copy of the Aho-Kernighan-Weinberger book; there are new and used copies available at Amazon.com ( http://www.amazon.com/s/ref=nb_ss?ur...07981x&x=0&y=0). They're the guys that invented it and their book is well-written and full of examples.
|
|
|
|
10-20-2009, 10:08 AM
|
#9
|
|
LQ 5k Club
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian Squeeze (server), Slackware 13.37 (netbook), Slackware64 14.0 (desktop),
Posts: 8,367
|
Quote:
Originally Posted by wakatana
I understand it that way
Code:
awk 'FS = "SOMETHING_WEIRD"; {if ($1 == "root") print $6666 }' /etc/passwd
Always will be printed whole file because I have not action before ';' so it execute default action print. And it never goes to second action (after ';') (I dont know why???)
|
It does go but the second action never does anything. Here's why. The next statement has no pattern so matches everything; its action is always executed. But the action has if ($1 == "root") and $1 is never root. The line for root is parsed before FS was set to ":". When line for root is parsed, FS has its default value, a space. The line has no spaces in it so awk puts the whole line in $1. Thus $1 does not match "root". For all the other lines FS is ":" and so awk parses the line as you intend. $1 is the user name but it is never root so does not match. That is why it is instructive to change "root" to "bin" -- and the bin line is printed.
|
|
|
|
10-20-2009, 10:15 AM
|
#10
|
|
LQ 5k Club
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian Squeeze (server), Slackware 13.37 (netbook), Slackware64 14.0 (desktop),
Posts: 8,367
|
Quote:
Originally Posted by wakatana
So in concusion declaring variables should be done in BEGIN block ? Or Am I wrong ?
|
I would not be so proscriptive but it is usual to initialise variables in either the command line or the BEGIN section -- and it helps make the awk program easy to understand.
If you want awk to parse the line with a particular IFS value the you must set that value before awk parses the line and then that must be in either the command line or the BEGIN section.
|
|
|
|
10-20-2009, 01:51 PM
|
#11
|
|
LQ Veteran
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Arch/XFCE
Posts: 17,797
|
Moved: This thread is more suitable in <Programming> and has been moved accordingly to help your thread/question get the exposure it deserves.
|
|
|
|
| Thread Tools |
Search this Thread |
|
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -5. The time now is 05:27 PM.
|
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|