0

For a simple file which contains:

1        a
2        b
3        c
4        d
5        e
6        f
7        g
8        h
9        i
10       j

I use that command:

awk 'lines[NR]=$0 { print $lines[2]}' 

It provides me:

1        a
b
c
d
e
f
g
h
i
j

How and why? Shouldn't it be that?

2 b

Also, when I update with following

awk '{lines[NR]=$0} END { print lines[2]}' awk.write

2 b

with use of $

j

2 Answers 2

2

You confused awks varibales and workflow. What you probably want is (print only the second line):

awk '{lines[NR]=$0} END{print lines[2]}' file

But this can be done much simpler by:

awk 'NR==2' file

You command your the question does the following:

awk 'lines[NR]=$0 { print $lines[2]}' 
  • lines[NR]=$0 this is interpreted by awk as a condition here. Notice, awk has a workflow that has a mechanism like this (that applies on every line): 'condition{instructions}'. lines[NR]=$0 fills the array, but nevertheless it is a condition which is always true. That's why the instructions {...} block run for every line.
  • print $lines[2] That doesn't print the second item of the array, lines[2] would. $lines[2] expands to a variable whose name is the contents of the second item in the array. For the first line, it's uninitialized, and thus print it called without argument. That means it prints the whole line. But when set (in all other lines), it's expanded to print $2. That means, print the second field of the line.
3
  • No, there's no variable b here, 2 b in numeric context return only 2.
    – cuonglm
    Commented Jan 6, 2016 at 8:28
  • @cuonglm Just tested it and found out, thanks anyway
    – chaos
    Commented Jan 6, 2016 at 8:29
  • And also, for the first line, lines[2] is uninitialized, not empty at all. It will be empty when evaluated in string context, and will be 0 when evaluated in numeric context.
    – cuonglm
    Commented Jan 6, 2016 at 8:33
0

In awk, you access a variable's value by referencing it:

$ awk 'BEGIN {var=1; print var}'
1

There're special variables, which are called field variables, denote by a $ symbol, followed by a number or an expression. So both $1 and $(0+1) give you the value of the first field.

In your example, you created an associative array lines, whose keys are the line number, values are the entire line. To get the value of key 2, you must use lines[2]. With $lines[2], you referred to the nth field, with nth is the value return by lines[2].

When you processed the first line, lines[2] is uninitialized, so it may return 0 or empty or whatever (the behavior is unspecified by POSIX). In any case, print and print $0 are the same, that's why you got 1 a, which is $0 of first line.

From second line, lines[2] is assigned by content of the second line, which is 2 b, and in numeric context, 2 b return 2, you got the value of second field $2 from the second line and so on.


Now, since the expression after $ is not guaranteed to return a numeric result as specified by POSIX:

Field variables shall be designated by a '$' followed by a number or numerical expression. The effect of the field number expression evaluating to anything other than a non-negative integer is unspecified; uninitialized variables or string values need not be converted to numeric values in this context

So there can be implementations will be broken. At least Brian Kernighan's own version:

$ echo 1 2 | bawk '{print $b}'
bawk: illegal field $(), name "b"
 input record number 1, file 
 source line number 1

In any case, you can force the expression to be evaluated in numeric context, by adding 0 to it:

$ echo 1 2 | awk '{print $(b+0)}'
1 2
5
  • Thanks a lot for explanation. So if lines[2] gives 2 b 2 b 2 b 2 b 2 b 2 b 2 b 2 b ` $lines[2] ` be nth value taken from results of above. Is that correct?
    – asad
    Commented Jan 6, 2016 at 8:50
  • 2 b in numeric context return 2, so you got print $2 for the rest of the lines.
    – cuonglm
    Commented Jan 6, 2016 at 8:51
  • Is there a correction you mentioned lines[2] twice in same context.?
    – asad
    Commented Jan 6, 2016 at 8:52
  • can you please view see the update to my question?
    – asad
    Commented Jan 6, 2016 at 9:24
  • Can you make it more clear?
    – cuonglm
    Commented Jan 6, 2016 at 9:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .