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 noticed an O'Reilly awk example (1997) which assigned an awk variable by setting it on the command line after the program-text. It does work, but I can't find this syntax in man / info awk. Have I just missed it; is it depricated...? The only syntax I've seen in the manual is the -v option.

awk '/home/{print foo, bar}' foo="cat" bar="dog" /proc/$$/cmdline

Output: cat dog

share|improve this question

2 Answers 2

up vote 9 down vote accepted

It's actually in POSIX awk (link to POSIX 2008, previous versions had it too I believe). -v is described in the Options section, the other way is in the Operands section.

There's a difference between -v and passing the assignments at the end with the file names:

  • With -v:

The application shall ensure that the assignment argument is in the same form as an assignment operand. The specified variable assignment shall occur prior to executing the awk program, including the actions associated with BEGIN patterns (if any). Multiple occurrences of this option can be specified.

  • Mixed in with the file names:

[...] Each such variable assignment shall occur just prior to the processing of the following file, if any. Thus, an assignment before the first file argument shall be executed after the BEGIN actions (if any), while an assignment after the last file argument shall occur before the END actions (if any). If there are no file arguments, assignments shall be executed before processing the standard input.

Example:

$ cat input 
hello
hello
$ awk -v var=one 'BEGIN{print var} /hello/{print var} END{print var}' \
    var=two input var=three input var=four
one
two
two
three
three
four
share|improve this answer
    
Wow! That adds some interesting control points... it's bound to come in handy. Thanks... –  Peter.O Mar 15 '12 at 17:42
    
My initial "Wow!" still holds, but it has been tempered somewhat by looking further into Arcege's answer... I tested it with a real file named "var=three" ... awk gave precedence to it being a variable assignment... This has a major corollary, ie. In all cases when a file name has this form, it will be ignored and the variable will be set... It seems that the only way to avoid this clash is by ensuring that file-names for the current working directory must always be prefixed with their relative path: ./var=three –  Peter.O Mar 16 '12 at 4:44
    
@Peter.O, yes, that's also among the reasons the -v syntax was introduced. You should think of the -v syntax as the preferred way to do assignments, going forward. –  dubiousjim Apr 19 '12 at 17:20

This is an old style of setting variables externally in awk. It was ambiguous (what if you had a filename named foo=cat), so later versions added a -v option. It should probably work for backward-compatibility, but you can't guarantee. And as I said, the -v option is newer, so not all versions of awk may support it.

share|improve this answer
    
Your comment on the possibility of a file-name clash is good...I've tested it and it is definitely a problem. I've written a bit more on it in a comment to Mat's answer.. Thansk for highlighting this issue (+1) –  Peter.O Mar 16 '12 at 4:42
1  
Actually, as explained in [Mats answer](http://unix.stackexchange.com/a/34258/9537), -v` and argument assignment are different in when they take effect. Also -v is in POSIX and should be present in all but the most ancient of awk implementations. Using ./ or making sure the file name contains a non-identifier character is probably the most reliable way to disambiguate. –  jw013 Nov 19 '12 at 17:22

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.