LinuxQuestions.org
Visit the LQ Articles and Editorials section
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 10-12-2012, 12:52 PM   #1
Thad E Ginataom
Member
 
Registered: Mar 2011
Distribution: Ubuntu 12.04 with KXStudio, MATE & Compiz
Posts: 46

Rep: Reputation: 7
How to read shell variables in awk


I just wrote this in another thread, then realised it was not what the OP was asking <Blush> Might come in useful to someone...

Here's some basic information about getting command line parameters to a shell script into awk. You do it by manipulating quotes. Here's an example:
Quote:
awk ' BEGIN { a="'$1'"; b="'$2'"; c="'$3'"; print a, b, c; }'
It is the red single quotes that matter there. The double quotes just prevent syntax errors when one or more of the positional parameters is empty, and will result in awk doing a="" rather than trying to do a=;. Think hard about what those single quotes do!

Look:
Code:
$  cat xxx
awk ' BEGIN { a="'$1'"; b="'$2'"; c="'$3'"; print a, b, c; }'
 $  ./xxx 1 2 3
1 2 3
lets add my favourite debugging method so we can see clearly what the shell is doing and what awk is seeing:
Code:
$  cat xxx
set -xv
awk ' BEGIN { a="'$1'"; b="'$2'"; c="'$3'"; print a, b, c; }'
 $  
 $  ./xxx frog pig dog
awk ' BEGIN { a="'$1'"; b="'$2'"; c="'$3'"; print a, b, c; }'
++ awk ' BEGIN { a="frog"; b="pig"; c="dog"; print a, b, c; }'
frog pig dog
 $
 
Old 10-12-2012, 03:11 PM   #2
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian
Posts: 2,494

Rep: Reputation: 850Reputation: 850Reputation: 850Reputation: 850Reputation: 850Reputation: 850Reputation: 850
You can save quoting effort with awk's -v option:
Code:
awk -va="$1" -vb="$2" -vc="$3" 'BEGIN { print a, b, c; }'
 
Old 10-12-2012, 11:48 PM   #3
grail
Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 7,562

Rep: Reputation: 1939Reputation: 1939Reputation: 1939Reputation: 1939Reputation: 1939Reputation: 1939Reputation: 1939Reputation: 1939Reputation: 1939Reputation: 1939Reputation: 1939
Well maybe a little overkill, but here is another alternative:
Code:
#!/bin/bash

awk 'BEGIN{for(i=1;i<(ARGC - 1);i++){print "do stuff with",ARGV[i];ARGV[i]=""}}' "$@" file
Then simply run the shell script as normal:
Code:
./script.sh one two three
 
1 members found this post helpful.
Old 10-13-2012, 03:10 AM   #4
Thad E Ginataom
Member
 
Registered: Mar 2011
Distribution: Ubuntu 12.04 with KXStudio, MATE & Compiz
Posts: 46

Original Poster
Rep: Reputation: 7
Ahh! ARGC and ARGV are the arguments to awk itself, and you have made the arguments to the shell script available by including $@ as the first argument.

It is elegant, and does not suffer the absolute dependency on getting the quotes right that my solution does. Getting those quotes right is not too bad on a one-liner, but can be a real headache in anything longer. Nice. Thanks.

Last edited by Thad E Ginataom; 10-13-2012 at 03:12 AM.
 
Old 10-13-2012, 12:45 PM   #5
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948
I also should point out that this is not quite safe as it stands:

Code:
awk 'BEGIN { a="'$1'"; b="'$2'"; c="'$3'"; print a, b, c; }'
    ^           ^  ^      ^  ^      ^  ^                   ^
    |===========|  |======|  |======|  |===================|
I highlighted the opening and closing quotes to make it clearer that the shell parameters have been left completely unprotected. If any of them contained multiple whitespace characters or globbing patterns that matched something in the current directory, you'd get incorrect expansion. This means that you need to include yet another set of double quotes to protect them.

Code:
awk 'BEGIN { a="'"$1"'"; b="'"$2"'"; c="'"$3"'"; print a, b, c; }'
Either that, or use double quotes to begin with, and backslash escape any quotes, dollar signs, or backslashes that need to appear in the expression itself (which can be quite a hassle in an awk script).

Code:
awk "BEGIN { a=\"$1\"; b=\"$2\"; c=\"$3\"; print a, b, c; }"
As you can see, it's really much easier and more readable to use awk's built-in variable importing feature.

Speaking of which, another option is the little-known feature in awk that lets you set up variables as arguments after the expression, and before the filename(s) that they apply to.

Code:
awk '{ print a, b, c }' a="$1" b="$2" c="$3" inputfile
 
1 members found this post helpful.
Old 10-13-2012, 02:52 PM   #6
Thad E Ginataom
Member
 
Registered: Mar 2011
Distribution: Ubuntu 12.04 with KXStudio, MATE & Compiz
Posts: 46

Original Poster
Rep: Reputation: 7
Quote:
I highlighted the opening and closing quotes to make it clearer that the shell parameters have been left completely unprotected.
Yes. The point is that the single quotes indicate what "belongs" to the shell and what "belongs" to awk. To put it more formally, what is expanded by the shell before calling awk with the result --- and there are often dangers such as you mention.

I think I should have a signature: ten years out of date and relearning! Because it's true, and I only realised the danger of not using the first set of " when I saw the syntax errors.
Quote:
Speaking of which, another option is the little-known feature in awk that lets you set up variables as arguments after the expression, and before the filename(s) that they apply to.
I like this best of all so far. Thanks.
 
  


Reply

Tags
awk, shell_variable


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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 variables danicobos Linux - General 7 10-27-2011 09:43 AM
[SOLVED] awk: how can I assign value to a shell variable inside awk? quanba Programming 6 03-23-2010 02:18 AM
shell command using awk fields inside awk one71 Programming 6 06-26-2008 04:11 PM
Shell variables in awk to define range fur Programming 1 09-01-2007 02:22 PM
Passing variables from AWK script to my shell script BigLarry Programming 1 06-12-2004 04:32 AM


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

Main Menu
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
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration