Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I am having some hard time with awk today. If I try to do:

df|awk '{print $2; $some=$2; print $some}'

It works as expected and I get the size of the disks twice but if I do:

df|awk '{$some=$2; print $some}'

I just get blank lines. Why is this happening? Something is maybe wrong in my understanding but why the usage of a field mandatory for subsequent fields to work? I also tried doing:

df|awk '{print "hello"; $some=$2; print $some}'

and I got some "hello", each separated by a newline. Where is $some=$2 lost?

My df command outputs:

Filesystem     1K-blocks     Used Available Use% Mounted on
/dev/sda5       38448788 32098732   4396932  88% /
udev             1914564        4   1914560   1% /dev
tmpfs             768744      984    767760   1% /run
share|improve this question
    
Can you post the output of your df command? –  Guru Mar 8 '13 at 10:52
    
@Guru I have added the output of df. –  Aditya Patawari Mar 8 '13 at 10:55
1  
$some in awk means field number some. (e.g. if some=13, then $some means 13th field) –  manatwork Mar 8 '13 at 10:57
    
Okay. Then how come first statement is working fine? –  Aditya Patawari Mar 8 '13 at 10:58
1  
@AdityaPatawari : I get correct results when I try in cygwin or linux...which OS and shell are you in? –  Guru Mar 8 '13 at 11:03
show 5 more comments

3 Answers

You should not use the $-sign in front of some. What happens is that with your first command $2 gets printed and then $some=$2 translates to $0=$2 since some is unitialized (in some awk implementations some gets converted from "" to 0, not all (then you get an error message)), so you are replacing the record ($0) with $2. Then you print $some, which means $0 So it is identical to

df|awk '{print $2; $0=$2; print $0}'

and

df|awk '{$0=$2; print $0}'

What you probably meant to do was:

df|awk '{print $2; some=$2; print some}'
share|improve this answer
    
I did try this before but it gave me an error: awk: program limit exceeded: maximum number of fields size=32767 –  Aditya Patawari Mar 8 '13 at 11:35
1  
@AdityaPatawari: Then what I suspect you did was: df|awk '{print $2; some=$2; print $some}' which would try to create field $38448788 with your sample input. –  Scrutinizer Mar 8 '13 at 11:36
    
that is quite possible. –  Aditya Patawari Mar 8 '13 at 11:47
add comment

I get the expected result. The first command prints each item twice. The second command prints it once.

This is rather unconventional - "some" will have the value of zero by default since it is undefined. $some is therefore $0, which represents the entire line, so basically you are replacing the line with whatever you find in $2 when you use $some=$2

Compare it with this result:

johan@computer:~$ df|awk '{$some=$2; print}'
1K-blocks
30827524
4041028
1621692
5120
4054228
102400
4054228
60555340
209548784

Why would you not get any output or a different result: I expect the behaviour of using uninitiated variables to be potentially undefined, at least on some systems.

On Solaris I have access to the "standard" awk as well as the supposedly POSIX compliant version installed in /usr/xpg4/bin/awk. Both of these produce the same result for the following

They produce varying results depending on whether I add print "hello" in front or not, and depending on whether I replace the last command with "print" (in stead of print $some) or not.

All of them print SOMETHING, not blanks, though - I have not managed to find a version that reproduces that effect.

So I expect this to be some kind of undefined behaviour due to using an un-initialized variable - you are assigning a value to a column, which is potentially far past the end of the possible range of columns in the input stream. $some refers to a column identified by the value of "some"

You should just use "some" as variable, eg

df | awk '{print "hello";some=$2; print some}'
share|improve this answer
add comment

I think the reason this happened is because Ubuntu does not use the standard GNU implantation but something else known as mawk which breaks a lot of code which worked under standard unix.

Please refer to this link for a similar discussion.

share|improve this answer
1  
This is completely bogus. Mawk and gawk are about on par on POSIX compliance (though the lack of support for character classes in mawk is a bug). The error here has nothing to with the choice of awk implementation. –  Gilles Mar 8 '13 at 22:23
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.