LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   How can I pass variable to "awk" and use print ? (https://www.linuxquestions.org/questions/linux-software-2/how-can-i-pass-variable-to-awk-and-use-print-896754/)

915086731 08-11-2011 08:51 AM

How can I pass variable to "awk" and use print ?
 
Problem comes with following command:
Code:

[saturn@localhost Desktop]$ a=2
[saturn@localhost Desktop]$ awk  'NR==2 {print $2}' about.txt
rights
[saturn@localhost Desktop]$ awk  "NR==2 {print $2}" about.txt
All rights reserved. Use is subject to license terms.          ????why print all fields????
[saturn@localhost Desktop]$ awk  "NR==$a {print $2}" about.txt
All rights reserved. Use is subject to license terms.          ????why print all fields????
[saturn@localhost Desktop]$ awk  'NR==$a {print $2}' about.txt
                                                              !!!print nothing!!!

Why does it print all fields? How to resolve it.
Thanks!!

mayursingru 08-11-2011 09:01 AM

Hi,
I think you are looking for this. Please correct me if i am wrong.

Code:

awk '{ if(FNR%2==0) print $2 }' filename

915086731 08-11-2011 09:13 AM

Sorry , I just want to use $a, not "2", may be $a is equal 3 .
And I want to use the format: NR==$a , not FNR%2==0
I don't know can it be realized or not .

catkin 08-11-2011 09:26 AM

In
Code:

awk  "NR==$a {print $2}" about.txt
presumably the shell's $2 is empty so it becomes
Code:

awk  "NR==2 {print }" about.txt
One way to solve it is to "backslash escape" the $2 so, after bash has substituted in the double quoted string it becomes
Code:

awk  "NR==2 {print $2}" about.txt
the code for that would be
Code:

awk  "NR==$a {print \$2}" about.txt

grail 08-11-2011 09:43 AM

So pass the variable to awk:
Code:

awk -va=$a 'NR==a {print $2}' about.txt

915086731 08-11-2011 10:02 AM

Yes, I get what I want.
but why?

catkin 08-11-2011 10:34 AM

Assuming you are replying to my post and not grail's it works because the $ in $2 is "backslash escaped"; the \ in front of $ tells bash not to treat the following $ specially so bash does not replace $2 with the value of $2, it simply passes the string $2 to awk which is what you want.

David the H. 08-11-2011 10:57 AM

When you post a question, it's usually helpful to give us all the relevant context of what you're doing.

In this case, you should give us a raw sample of the input text and the exact data, and format, that you want to extract from it, in addition to the command itself.

It also helps to explain what you're doing and why. Is the awk command being used inside a script, for example, or just on the command line?

Anyway, remember that awk has a different variable system from your shell. You can't use bash variables in an awk command without either importing them with the "-v" option or using complex quoting.

Code:

$ echo "foo bar baz" > file.txt

$ bashvar=3
$ echo "$bashvar"
3

$ awk -v awkvar="$bashvar" '{ print awkvar , $awkvar }' file.txt
3 baz

"bashvar" is a bash variable, in this case it contains the number "3".
"awkvar" is an awk variable, which we set to the value of "$bashvar" using the -v option.

Using an awk variable alone (without the "$") prints the value it contains, in this case "3". When you add the "$" to it, it will now reference the value of the input text field of the number stored in the variable (if any), which in this case is field number 3 or "baz".

Here are a few useful awk references:
http://www.grymoire.com/Unix/Awk.html
http://www.gnu.org/software/gawk/man...ode/index.html
http://www.informatik.uni-hamburg.de.../gawk_toc.html
http://www.pement.org/awk/awk1line.txt
http://www.catonmat.net/blog/awk-one...ined-part-one/

PTrenholme 08-11-2011 11:37 AM

Also, your use of double-quotes (") around the awk program string instructs the shell to parse the string, which, for example, will remove the curly bracket symbols. The single-quote passes the contents verbatim. So, the you examples where you used the double-quotes, there was no process section defined, and the default awk process is to copy the input to the output.

catkin 08-11-2011 02:50 PM

Quote:

Originally Posted by PTrenholme (Post 4439829)
Also, your use of double-quotes (") around the awk program string instructs the shell to parse the string, which, for example, will remove the curly bracket symbols.

AFAIK that is not correct when applied to { ... } which do not have a preceding $, which is the common case when the double quoted string is an awk program. From the GNU Bash Reference on double quotes:

3.1.2.3 Double Quotes

Enclosing characters in double quotes (‘"’) preserves the literal value of all characters within the quotes, with the exception of ‘$’, ‘`’, ‘\’, and, when history expansion is enabled, ‘!’. The characters ‘$’ and ‘`’ retain their special meaning within double quotes (see Shell Expansions). The backslash retains its special meaning only when followed by one of the following characters: ‘$’, ‘`’, ‘"’, ‘\’, or newline. Within double quotes, backslashes that are followed by one of these characters are removed. Backslashes preceding characters without a special meaning are left unmodified. A double quote may be quoted within double quotes by preceding it with a backslash. If enabled, history expansion will be performed unless an ‘!’ appearing in double quotes is escaped using a backslash. The backslash preceding the ‘!’ is not removed.


Bash will remove curly brackets following a $, as in it will substitute the value of bashvar when it finds ${bashvar} and other similar ${ ... } bash parameter expansions.

PTrenholme 08-11-2011 06:33 PM

Quote:

Originally Posted by catkin (Post 4440059)
AFAIK that is not correct when applied to { ... } which do not have a preceding $, which is the common case when the double quoted string is an awk program. [...]

O.K., :redface:

I should have used the $<number> example, not the {...} one. The point I was trying to make was just that bash does mess with the contents of double-quoted strings, but not with single-quoted ones.

915086731 08-11-2011 09:35 PM

Thanks all.


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