LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
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


Reply
  Search this Thread
Old 01-13-2010, 11:37 AM   #1
suresh.chola
LQ Newbie
 
Registered: Jan 2010
Posts: 8

Rep: Reputation: 0
updating a field in a record through AWK


I have a record and need to update a particular field in that record.

Here is my code:
TargetFld=`echo TargetRec|cut -d',' -f3`
TargetFld=`sed -e s/cycle/$cycle/ $TargetLoc`
TargetRec=`echo $1|awk -F ',' '{print $1","$2","$TargetLoc","$4","$5","$6","$7","$8","$9","$10","$11}'`

As you can see i am just printing all fields one by one...
First of all is this correct approach?
Is there any better way to update the 3rd field in a record.

Thanks in Advance
Suresh
 
Old 01-13-2010, 02:02 PM   #2
Tinkster
Moderator
 
Registered: Apr 2002
Location: earth
Distribution: slackware by choice, others too :} ... android.
Posts: 23,067
Blog Entries: 11

Rep: Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928
Hi,

Your only problem is that you can't use the shell variables
directly in the awk statement.

Read "man awk", search for "- v".


Cheers,
Tink
 
Old 01-13-2010, 03:22 PM   #3
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983
Quote:
Originally Posted by suresh.chola View Post
Is there any better way to update the 3rd field in a record.
Yes. Using the sub or the gsub function you can alter the content of a field. After having followed the advice by Tinkster, you can try something like:
Code:
'{sub($3,replacement,$3); print}'
In addition to the man page of awk suggested above, you can consult the GNU Awk User's Guide... a must-read!
 
Old 01-14-2010, 03:12 AM   #4
suresh.chola
LQ Newbie
 
Registered: Jan 2010
Posts: 8

Original Poster
Rep: Reputation: 0
Thanks Guys.

I got my final code like this:

TargetLoc=`echo $1|cut -d',' -f3`
if [ `echo $TargetLoc|grep <year>` != "" ]; then
NewTargerRec=`echo ${$1/year/$year}`
TargetRec=$NewTargetRec
fi

However, i didn't understand few things while I am working on this.
When i tried with sub funciton like below :

str="customer,234/34,ET-Street,<year>,Active"
week=2009
Newstr=`echo $str| awk -F ',' { sub($4/$week); print`

This didnt wont as there is a problem with $week substitution.

if i give as below, it's working.
Newstr=`echo $str| awk -F ',' { sub($4/200901); print`

I heard that, in ksh and bash all the variables are global.
So, can't I use $week which is outside awk statement in the above awk statment.
Is this due to variable scoping.

And by the way, i didnt find "awk -v" option useful in my above problem.
I am sorry, am I missing something there...

Thanks for your responses guys.

Suresh

Last edited by suresh.chola; 01-14-2010 at 04:16 AM.
 
Old 01-14-2010, 10:09 AM   #5
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983
Quote:
Originally Posted by suresh.chola View Post
Newstr=`echo $str| awk -F ',' { sub($4/200901); print`
Sorry, Suresh, but your code is a bit unreadable and full of syntax errors. It's difficult to provide a good reply to your questions under these condition.

Please, use CODE tags to embed your code when posting (to do that you can switch to Advanced mode, then select the lines you want to embed and press the # (hash) button in the task bar at the top of the text box). This will also preserve indentation and spacing. Furthermore, try to copy/paste the lines from your terminal or from your script to avoid typos as possible.
 
Old 01-14-2010, 11:59 PM   #6
suresh.chola
LQ Newbie
 
Registered: Jan 2010
Posts: 8

Original Poster
Rep: Reputation: 0
Sorry for that, Colucix.

I was in bit hurry and didn't paste the actual code.
Thanks for your tips.

Here is the code:
Code:
$ more test1.sh
str="customer,234/34,ET-Street,<year>,Active"
week=2009
newstr=`echo $str|awk -F ',' '{ sub($4,200901); print}'

$ sh test1.sh
$ echo $newstr
customer,234/34,ET-Street,200901,Active
Here is the second code:
Code:
$more test2.sh
str="customer,234/34,ET-Street,<year>,Active"
week=2009
newstr=`echo $str|awk -F ',' '{ sub($4,$week); print}'`

$sh test2.sh
$ echo $newstr
customer,234/34,ET-Street,customer,234/34,ET-Street,<year>,Active,Active
My question is: Why $week is not giving the desired result in the test2. If i give the value of $week then it is working fine as shown in test1.

Is there any scoping(Global and Local) of the variables in bash.

Please let me know if you need more explanation, I am more than happy to provide.

Thanks,
Suresh

Last edited by suresh.chola; 01-15-2010 at 12:10 AM.
 
Old 01-15-2010, 02:25 AM   #7
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
It's because $week in awk is not the same variable as $week in bash.

You have to understand that awk has it's own, slightly different, variable system. In addition, even as a bash variable, the ' hard-quoting turns off substitution for it.

As tinkster said, you have to use the -v option (or careful quoting), in order to import the bash variable into the awk statement.

This awk tutorial is a recommended read. Give it a whirl.
http://www.grymoire.com/Unix/Awk.html
 
Old 01-15-2010, 02:59 AM   #8
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
For the record, this should fix your script.
Code:
str="customer,234/34,ET-Street,<year>,Active"
week=2009
newstr=$(echo "$str"|awk -F ',' -v "wk=$week" '{ sub($4,wk); print}')
Unlike bash, awk variables are substituted by name only, with no '$' in front of them. When the dollar sign is included, awk will print the contents of the column (or whatever the substituted value refers to) from the input text. Using $wk in the above would make awk try to print the contents of column number 2009, for example.

Also note the (") soft-quoting of the -v value. Unlike single-quotes, double-quotes allow for bash variable substitution.

Finally, backticks (`) are discouraged in bash these days. The $() form is recommended as more robust and readable. See here.

Last edited by David the H.; 01-15-2010 at 03:10 AM. Reason: fixed typo
 
1 members found this post helpful.
Old 01-15-2010, 04:26 PM   #9
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983
David the H. already provided an exhaustive explanation (thanks). Just a little add-on to explain why you got a weird result in the second test.

The syntax of the sub function in awk is:
Code:
sub(regexp, replacement [, target])
as you can see you may pass two or three arguments. You chose to pass only two, so that the substitution is applied to the whole line (record in awk).

The regexp, that is the regular expression that matches the part of the string you want to substitute is $4 in your statement, that is "<year>".

The replacement is $week, that in awk code - as David pointed out - is a reference to a field. week in this case is a variable to which you didn't assign any value (inside the awk code), so that it retains a value of 0. Therefore, the resulting substitution is:
Code:
sub($4,$0)
which means substitute the text matching the fourth field with the whole record. The result is indeed:
Code:
customer,234/34,ET-Street,customer,234/34,ET-Street,<year>,Active,Active
where the substituted part is highlighted in blue. Hope this helps. Cheers!

Last edited by colucix; 01-15-2010 at 04:27 PM.
 
1 members found this post helpful.
Old 01-18-2010, 08:07 AM   #10
suresh.chola
LQ Newbie
 
Registered: Jan 2010
Posts: 8

Original Poster
Rep: Reputation: 0
All your answers helped me a lot.
Thanks a million guys.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
awk printing from Nth field to last field sebelk Programming 2 01-08-2010 09:39 AM
awk to replace particular field vgr12386 Programming 9 06-05-2009 07:15 AM
deleting a field using awk jkeertir Linux - Newbie 5 04-13-2008 10:55 PM
My field separator changes when using awk Helene Programming 3 05-01-2004 08:10 AM
Two field seperators in awk?? Astro Programming 2 11-09-2003 10:12 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 09:03 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration