[net.unix] You can pass *anything* to awk: even in BEGIN!

jmr@motown.UUCP (John M. Ritter) (09/22/86)

> It's not as easy as using a $1 in a shell script but you can define the value
> of variables on the command line. This feature is not really documented. 
> _The_UNIX_System_User's_Manual_ from AT&T comes the closest. It gives the
> SYNOPSIS as this:
> 	awk [-Fc] [-f progfile] ['program'] [parameters] [file...]
> [ ... ]				     ^^^^^^^^^^
> What it doesn't tell you is this: [ ... ]
>
>	5) This information is not available within the BEGIN block.
>	   It will only become available after the first record has
>	   been read and parsed. Therefore if the input is empty it
>	   will not be available within the END block either.	
>
>	dph@lanl.arpa

I thought this was beat to death a couple of months ago, and I'd like to
present the method I use as it seems to cover every situation.

This method DOES allow initialization within the BEGIN block, and it is
also as easy to use as $1 in a shell script...

I can't think of anything that has been left out. This is using
System V, r2.0v2 - I'd love to know if this works on other versions
of Unix.
------------------------------------------------------------------------------
"I enjoy working with human beings, and                         John M. Ritter
have stimulating relationships with them."                  Allied-Signal Inc.
                            - HAL 9000                Corporate Tax Department
                      {bellcore,harpo,ihnp4,infopro,princeton,sys1}!motown!jmr
------------------------------------------------------------------------------
# awk script to receive arguments from three places:
#	1) Environment (must be exported)
#	2) Initialized within the awk script
#	3) Entered on the command line
#
# execute the script with something like:
#	script argument_1 argument_2

ARG2=$2				# second command argument: Can be identified
				#	here, or in the BEGIN section.
VAR1=something_here		# single argument
VAR2="something else"		# two words is twice the fun

echo " " |
awk '
BEGIN { TERM = "'$TERM'";	# From Environment
	VAR1 = "'$VAR1'";	# From Above
	VAR2 = "'"$VAR2"'";	# From Above: Note strange quotes!
	ARG1 = "'$1'";		# From command line - direct
	ARG2 = "'$ARG2'";	# From command line but identified above
	ESC = 27;		# define ESCAPE code

	if (TERM == "vt100") 	{ REV_ON  = sprintf("%c[7m", ESC);
				  REV_OFF = sprintf("%c[m", ESC);}
      } # End of BEGIN

{	print "Your terminal is: " REV_ON TERM REV_OFF;
	print "VAR1 = " VAR1;
	print "VAR2 = " VAR2;
	print "Command argument 1: " ARG1;
	print "Command argument 2: " ARG2;
}'

jerryp@tektools.UUCP (Jerry Peek) (09/24/86)

In article <185@motown.UUCP> jmr@motown.UUCP (John M. Ritter) writes:
> awk '
> BEGIN { TERM = "'$TERM'";	# From Environment
> 	VAR1 = "'$VAR1'";	# From Above
> 	VAR2 = "'"$VAR2"'";	# From Above: Note strange quotes!
   ...etc...
>       } # End of BEGIN
>
> This method DOES allow initialization within the BEGIN block, and it is
> also as easy to use as $1 in a shell script...
> 
> I can't think of anything that has been left out. This is using
> System V, r2.0v2 - I'd love to know if this works on other versions
> of Unix.

Seems like this should work everywhere (unless I'm missing something?); it's
dependent on the quoting behavior of the *shell*, not awk.  You just have to
make sure that the shell plugs in the values before it invokes "awk".

I've been taking this a step farther, to let me define arbitrary variables
(or array members) within an "awk" BEGIN block.  First, I write a
shell script which outputs strings of the form:

	VAR = "some junk"
	array["member 1"] = "VALUE 1"
	array["member 2"] = "VALUE 2"

... these are the variable-assignment commands you want "awk" to do.
(They might include things that vary, day-to-day, like the output of "date"
or "who" or "uptime" or...)  Let's call that program "mkawkvars".

Then, you put the "mkawkvars" output into your awk script.  Use the shell's
command-substitution feature (backquotes or grave accents), like this:

	awk "
	BEGIN { `mkawkvars`"' }
	{
	     ...rest of awk script...
	}'

The quoting is important.  The first section of the script has doublequotes (")
around it.  That's because:

	- the command-substitution (`mkawkvars`) won't work if you enclose it
	  within singlequotes('`mkawkvars`').

	- the mkawkvars script must output newlines after every
	  variable-assignment command.  If you don't quote the 
	  mkawkvars output at all, the newlines disappear; awk
	  will see all the variable assignments on one line, like this:

		VAR = "some junk" array["member 1"] = "VALUE 1" array[...

	  ... causing "awk: bailing out near line 2..." :-)

You can surround the first part of the BEGIN block with doublequotes, then
switch to singlequotes (as I did above) after `mkawkvars` has been executed.

This article is too long already, so I won't include any more examples.
If anyone's interested, though, send me mail and I'll send you a copy
of a working script.

--Jerry Peek, Tektronix, Inc.
US Mail:    MS 74-900, P.O. Box 500, Beaverton, OR 97077
uucp:       {allegra,decvax,hplabs,ihnp4,ucbvax}!tektronix!tektools!jerryp
CS,ARPAnet: jerryp%tektools@tektronix.csnet
Phone:      +1 503 627-1603