5

I have an input file file the content of which constantly is updated with various number of fields, what I am trying to is to print out to a new file the next to last field of each line of input file: awk '{print $(NF-1)}' outputfile

error: and awk: (FILENAME=- FNR=2) fatal: attempt to access field -1

Need help. Thanks in advance

Zerg12
  • 307
  • 2
  • 5
  • 19

3 Answers3

9

On lines with no fields (blank lines, or all whitespace) NF is 0, so that evaluates to $(-1). Also if there's only one field your code will print $0 which may not be what you want.

awk 'NF>=2 {print $(NF-1)}'
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
3

Should be awk 'NF > 1 { print $(NF - 1); }'

awk 'NF { print $(NF - 1) }' is not correct. When NF == 1 it'll print $0 which is not next to the last field.

pynexj
  • 19,215
  • 5
  • 38
  • 56
  • +1 for the solution but lose the null statement (trailing semi-colon) – Ed Morton Mar 27 '13 at 15:29
  • @EdMorton: What do you mean by *"but lose the null statement (trailing semi-colon)"*? – pynexj Mar 28 '13 at 02:29
  • 2
    The semi-colon after the statement `print $(NF - 1)` introduces a subsequent statement which is empty/null. Just get rid of the semi-colon and that solves the problem, i.e. use `{ print $(NF - 1) }` not `{ print $(NF - 1); }`. – Ed Morton Mar 28 '13 at 03:39
  • That's my style. I'd like to make it look more like a statement. :) – pynexj Mar 28 '13 at 03:41
  • Well, I guess there's worse things you can do than add spurious semi-colons to your code and I don't think there's any functional breakage due to it. Not sure I understand the attraction though, to be honest, and when I see that in a script it always takes me a little longer reading the code to convince myself that it's truly not doing anything non-obvious so I get irked by it but that might just be me... – Ed Morton Mar 28 '13 at 06:17
  • 3
    To clarify why it gets me wasting time and frustrated when I see spurious semi-colons - there's a huge difference between what these 2 statements will do: `x > y { print }` and `x > y; { print; }`. Similarly for `{x = a b}` and `{x = a; b;}`. So when you throw in semi-colons with the intent of them not doing anything, my initial thought is to figure out what it is they ARE doing since the placement of semi-colons often has a big impact on your program and then when I convince myself it's not doing anything and it's a "style choice" instead then the annoyance ensues.... – Ed Morton Mar 28 '13 at 14:19
-1

another awk line: (golfing a bit):

awk 'NF>1&&$0=$(NF-1)' 
Kent
  • 189,393
  • 32
  • 233
  • 301