[net.unix] passing command line arguments to awk

craig@comp.lancs.ac.uk (Craig Wylie) (05/28/86)

I surrender  --  is it possible to pass command line arguments to awk?

If so - how.  While I'm at it how about doing the same thing to sed.


Craig.

-- 
UUCP:	 ...!seismo!mcvax!ukc!dcl-cs!craig| Post: University of Lancaster,
DARPA:	 craig%lancs.comp@ucl-cs 	  |	  Department of Computing,
JANET:	 craig@uk.ac.lancs.comp		  |	  Bailrigg, Lancaster, UK.
Phone:	 +44 524 65201 Ext. 4146   	  |	  LA1 4YR
Project: Cosmos Distributed Operating Systems Research Group

zben@umd5.UUCP (Ben Cranston) (05/30/86)

In article <198@comp.lancs.ac.uk> craig@comp.lancs.ac.uk (Craig Wylie) writes:
>I surrender  --  is it possible to pass command line arguments to awk?
>If so - how.  While I'm at it how about doing the same thing to sed.

I'm not sure if this is really what you are asking.  You can use $n type
substitution if you use double-quotes to delimit the program; however;
beware that now all double-quotes and dollar signs in the program must 
be escaped with a backslash.  Consider the following shell script, which
looks a site up in the ARPA Internet site table:

#! /bin/sh
# host: Search InterNet host table for pattern
case $1 in
-a|-A) source=/u/netmap/hosts.txt; shift;;
*)     source=/u/netmap/lochosts.txt;;
esac
case $# in
0) echo 'Usage: host [-a] pattern' 1>&2; exit 2;;
esac
grep -i -e $1 <$source |
sed 's/ //g' |
awk -F: "
BEGIN { nf=0 }
\$1==\"HOST\" {
  if (\$4==\"\")
     \$4 = \"(Unknown)\"
  if (\$5==\"\")
     \$5 = \"(unknown)\"
  printf \"\n\"
  printf \"%s running %s with InterNet address %s\n\", \$4, \$5, \$2
  printf \"Names:    %s\n\", \$3
  printf \"Services: %s\n\", \$6
  nf += 1
}
END { 
  if (nf==0)
     print | \"echo $1 not found in $source 1>&2\" 
} " |
more -20

The substitution I am talking about is in the "if (nf==0)" clause at the
end - so it can say "luser.podunk.EDU not found" if it doesn't find it.

Is that what you wanted?
-- 
"We're taught to cherish what we have   |          Ben Cranston
 by what we have no longer..."          |          zben@umd2.umd.edu
                          ...{seismo!umcp-cs,ihnp4!rlgvax}!cvl!umd5!zben  

jmr@motown.UUCP (John M. Ritter) (05/30/86)

> I surrender  --  is it possible to pass command line arguments to awk?
> If so - how.  While I'm at it how about doing the same thing to sed.
> Craig.

Well, I know the feeling. A few months ago I was presented with this same
situation and it drove me crazy. It's really fairly simple. I've posted an
answer as I know several people have come across this.

I've included a section of code from an awk script that pulls stuff from the
environment. No real changes to make the variables command line arguments.
The script also shows another problem I had - how to imbed control codes
for "fun stuff". I had to find a way to avoid sticking a true \033 in the
middle of the script.

As for sed, I just do something like this:

FIND="search"
CHANGE="new string"
echo "We'll search for some stuff and send it to sed." |
sed -e s/$FIND/"$CHANGE"/

Hope this helps!
------------------------------------------------------------------------------
"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
------------------------------------------------------------------------------

# Simple awk script to receive passing parameters
PHRASE1="Hello_world."
PHRASE2="Hello world."

echo " " |
awk '
BEGIN {
# Have to put environment stuff "outside" of awk
	TERM = "'$TERM'"		# From Environment
	PHRASE1 = "'$PHRASE1'"		# From Environment
# Note weird quotes. Have to pass as one variable.
# If quoting structure was the same as above - disaster:
	PHRASE2 = "'"$PHRASE2"'"	# From Environment

	ESC = 27
	if (TERM == "wy75") {
		REVERSE_ON  = sprintf("%c%s", ESC, "[7m")
		REVERSE_OFF = sprintf("%c%s", ESC, "[m")
	}
	if (TERM == "adds25") {
		REVERSE_ON  = sprintf("%c%s", ESC, "G4")
		REVERSE_OFF = sprintf("%c%s", ESC, "G0")
	}
} # End of BEGIN

{ print REVERSE_ON PHRASE1 REVERSE_OFF
  print REVERSE_ON PHRASE2 REVERSE_OFF}'

onn@utcs.uucp (Brian Onn) (05/31/86)

In article <198@comp.lancs.ac.uk> craig@comp.lancs.ac.uk (Craig Wylie) writes:
>
>I surrender  --  is it possible to pass command line arguments to awk?
>
>If so - how.  While I'm at it how about doing the same thing to sed.
>
>
>Craig.

The only way I know of to pass command line arguments into awk is by
defining them as variables in an assign statement on the awk command line, ie

awk -f awkfile arg1=$1 arg2=$2 inputfile

will assign $1 to arg1, and $2 to arg2, inside the body of the awk program. It
is not possible to assign variable values in this manner to variables that
are used inside an action associated with the BEGIN pattern.

I am not sure how to do it with sed.

-- 
-----
Brian A. Onn
University of Toronto Computing Services
Erindale College.
..!{ihnp4,decvax,harpo,utcsri,{allegra,linus}!utzoo}!utcs!onn

    "We trained hard, but it seemed that every time we were beginning to
     form up into teams, we would be reorganized.  I was to learn later in
     life we tend to meet any new situation by reorganizing, and a wonderful
     method it can be for creating the illusion of progress while producing
     confusion, inefficiency and demoralization"
						 - Petronius Arbiter, 66 AD.

neil@sunybcs.UUCP (Neil Smithline) (06/02/86)

In article <1261@utcs.uucp> onn@utcs.UUCP (Brian Onn) writes:
>In article <198@comp.lancs.ac.uk> craig@comp.lancs.ac.uk (Craig Wylie) writes:
>>
>>I surrender  --  is it possible to pass command line arguments to awk?
>>
>>If so - how.  While I'm at it how about doing the same thing to sed.
>>
>>
>>Craig.
>
>The only way I know of to pass command line arguments into awk is by
>defining them as variables in an assign statement on the awk command line, ie
>
>awk -f awkfile arg1=$1 arg2=$2 inputfile
>
>will assign $1 to arg1, and $2 to arg2, inside the body of the awk program. It
>is not possible to assign variable values in this manner to variables that
>are used inside an action associated with the BEGIN pattern.

There is a much more general method to use.  If you put the awk code inside of 
the shell script (rather than using the 'awk -f' option) it can be done as
follows:
-----------------------------------------------------------------------------
#!/bin/csh -f
awk ' {awkvar = '$1'; printf("awkvar: %s, shellvar: %s\n",awkvar,'$1')}'
-----------------------------------------------------------------------------
This program will wait for you to enter a line of input (awk always waits for
this - it is not essential for the program to work - just for awk to work), and
then print out the first argument to the shell twice.  The way that this is done
is by closing the single quotes (') every time you want to access a shell 
variable and then reopening them afterwards.  In the above script the "$1"
refers to the first argument to the shell and not to the first word of the
input line.  This can be done the same way for sed (or any other program for
that matter) because it is not making use of any features of awk but rather
those of the shell - Neil

pdg@ihdev.UUCP (P. D. Guthrie) (06/02/86)

Newer versions of awk have direct command line argument access through
the pseudo-variables ARGC and ARGV.  ARGV[0] is  naturally the programme
name as invoked.  If stdin is used for input, '-' is added as the last
argument.
-- 

Paul Guthrie		`See the happy moron, he doesn't give a damn.
ihnp4!ihdev!pdg		 I wish I were a moron. My God! Perhaps I am.'

guy@sun.uucp (Guy Harris) (06/03/86)

> Newer versions of awk have direct command line argument access through
> the pseudo-variables ARGC and ARGV.

How new is "newer"?  It's certainly not in the S5R2 version.  Is it in S5R3,
or is it only in the new whizzo BTL (sorry, AT&T-BL) Research version?  If
so, when does the world as a whole see it?
-- 
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.com (or guy@sun.arpa)

jwp@sdchem.UUCP (John Pierce) (06/04/86)

Somebody:
> >awk -f awkfile arg1=$1 arg2=$2 inputfile
> >
> >will assign $1 to arg1, and $2 to arg2, inside the body of the awk program.
> >It is not possible to assign variable values in this manner to variables
> >that are used inside an action associated with the BEGIN pattern.

This is correct.

Somebody else:
> There is a much more general method to use. If you put the awk code inside of 
> the shell script [and use the shell to expand args]...

Also correct, but I'm not sure it's more "general", or useful.  It must get
very interesting typing five hundred lines of awk script into a file the shell
is going to parse first....

There were references to new versions of awk that appear to have considerably
more capabilities than the one distributed with BSD and Sys V (or at least the
version of Sys V on the campus 3B20s).  Can anybody tell me where they come
from, and whether or not they're available?  [Of course, I can probably guess
the answer to both of those.]
-- 
	John Pierce			Chemistry Dept, B-032
	jwp%chem@sdcsvax.ucsd.edu	University of California, San Diego
	sdcsvax!sdchem!jwp		La Jolla, CA  92093
					+1 619 452 4016

de@moscom.UUCP (Dave Esan) (09/19/86)

> 
> I surrender  --  is it possible to pass command line arguments to awk?
> 
> If so - how.  While I'm at it how about doing the same thing to sed.

I don't use awk that much, but I'm sure its possible.  As for sed:

Suppose that you want to substitute A for B.  Your command could be:    

(executable file) A B, where executable file contains the line:
       
	sed "s/$1/$2/" editingfilename.

There are many other combinations, which of course is the wonder that is
UN*X.

               rochester \
David Esan                | moscom ! de
                    ritcv/

steiny@scc.UUCP (Don Steiny) (09/21/86)

In article <753@moscom.UUCP>, de@moscom.UUCP (Dave Esan) writes:
> > 
> > I surrender  --  is it possible to pass command line arguments to awk?
> > If so - how.  

	awk ' statement ; . . . ' file

be sure and use single quotes!   Lots of awk characters have
special meaning to the shell.  The following prints the uids in
the password file from highest to lowest:

	awk -F: '{ print $3 }' | sort -n -r


-- 
scc!steiny
Don Steiny @ Don Steiny Software 
109 Torrey Pine Terrace
Santa Cruz, Calif. 95060
(408) 425-0382

dph@lanl.ARPA (David P Huelsbeck) (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...]
					     ^^^^^^^^^^

It doesn't give any more information about it. However at the end of the
examples it gives this:

>	Print file, filling in page number starting at 5:
>	
>		/Page/ { $2 = n++; } 
>		    { print }
>
>	command line:
>
>		awk -f program n=5 input

Disregarding the fact that this program won't work it does give the general
idea. What it doesn't tell you is this:

	1) You may pass as many <parameters> as you wish provided
	   that the appear between the <program> or -f <progfile>
	   and the firist <file> name.

	2) Each <parameter> assignment must be a single argument.
	   This means no spaces. ( <parameter>=<value> )

	3) Value can as usual be a string or a number. String values
	   however must be enclosed in qoutes WHEN AWK SEE THEM. This
	   means that the double-qoutes must be protected from the shell.
	   (awk -f program stringp=\"avalue\" yourfile)

	4) Environmet variables may be passed this way.
	   (awk -f program dir=\"`pwd`\" file1 file2)

	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

PS: The reason why the program example from the AT&T doc's won't work is
    that "print" is only the default action. Once you do something else
    that something else replaces "print" as the action for that record.
    In 4.2 adding a "print" to the first action still won't make it work
    because assignments to fields other than $0 don't effect $0. This
    bug is fixed in 4.3 and the SysV that I've seen.

dph@lanl.ARPA (David P Huelsbeck) (09/22/86)

In article <731@scc.UUCP> steiny@scc.UUCP (Don Steiny) writes:
>In article <753@moscom.UUCP>, de@moscom.UUCP (Dave Esan) writes:
>> > 
>> > I surrender  --  is it possible to pass command line arguments to awk?
>> > If so - how.  
>
>	awk ' statement ; . . . ' file
>
>be sure and use single quotes!   Lots of awk characters have
>special meaning to the shell.  The following prints the uids in
>the password file from highest to lowest:
>
>	awk -F: '{ print $3 }' | sort -n -r
>
>
>-- 
>scc!steiny
>Don Steiny @ Don Steiny Software 
>109 Torrey Pine Terrace
>Santa Cruz, Calif. 95060
>(408) 425-0382


This is a special case but an important one. Using the -F<c> option sets the
field separator to the character <c>. This is important because setting the
field separator with:

	awk '{ print $3 }' FS=\":\" | sort -n -r

will not set the FS variable to ":". (at least on 4.2) I haven't checked but
I suspect that it's caused by the fact that parameter values passed from the 
command line are not made available until after the first record has been read
and parsed. Other variables not used in parsing (such as OFS etc.) may be set
in the way I've shown. In the case of RS I know of no way to set it from the
command line.

	dph@lanl.arpa

msitd22@ms3.UUCP (Jim Chappell) (09/22/86)

In article <731@scc.UUCP>, steiny@scc.UUCP (Don Steiny) writes:
> In article <753@moscom.UUCP>, de@moscom.UUCP (Dave Esan) writes:
> > > 
> > > I surrender  --  is it possible to pass command line arguments to awk?
> > > If so - how.  
> 
> 	awk ' statement ; . . . ' file
> 
> be sure and use single quotes!   Lots of awk characters have
> special meaning to the shell.  The following prints the uids in
> the password file from highest to lowest:
> 
> 	awk -F: '{ print $3 }' | sort -n -r


I bet it sits there forever more because of missing input, viz:


> 	awk -F: '{ print $3 }' \
				/etc/passwd \
>						 | sort -n -r


Why not use the capabilities of awk documented in my (but maybe not your)
users manual:

SYNOPSIS
	awk [ -Fc } [ prog ] [ parameters ] [ files ]
			     ^^^^^^^^^^^^^^

...
	_parameters_ in the form of x=...y=...etc., may be passed to awk.



Here's the stub of a script I use to produce reports by month of year, and
need to know how many days are in the month:

awk '{ ...

	printf "Report for %s\n\n",month
	for (i=1; i<=dm; i++)
	...

      } ' month=$1 \
	dm=`case $1 in
	Jan|Mar|May|Jul|Aug|Oct|Dec) echo 31;;
	Feb) echo 28;;
	Apr|Jun|Sep|Nov) echo 31;;
     esac`  data


Jim
-- 
Jim Chappell  ...!seismo!vrdxhq!ms3!jrc 
ISN Corp.
1235A Jeff Davis Hwy, Suite 605A
Arlington, Va 22202

leiby@masscomp.UUCP (Mike Leibensperger) (09/23/86)

In article <753@moscom.UUCP> de@moscom.UUCP (Dave Esan) quotes someone else:
>> 
>> I surrender  --  is it possible to pass command line arguments to awk?
>> 
>> If so - how.  While I'm at it how about doing the same thing to sed.

One way to do it is to put your awk command in a shell script, and play
with shell quoting to put the shell arguments where you want them.
This example,

	:
	awk '{ s += $'$1' }
	END { print s }'


from _The_UNIX_Programming_Environment_ by Kernighan and Pike, shows the
basic idea.
--
Rt. Rev. Mike Leibensperger, Archbishop of Chelmsford
Church of St. Clint the Righteous  ("Feel lucky, Pink Boy?")
Masscomp; 1 Technology Park; Westford, MA 01886
{decvax,ihnp4,tektronix}!masscomp!leiby

steiny@scc.UUCP (Don Steiny) (09/24/86)

In article <482@ms3.UUCP>, msitd22@ms3.UUCP (Jim Chappell) writes:
> In article <731@scc.UUCP>, steiny@scc.UUCP (Don Steiny) writes:
> > In article <753@moscom.UUCP>, de@moscom.UUCP (Dave Esan) writes:
> > > > 
> > > > I surrender  --  is it possible to pass command line arguments to awk?
> > > > If so - how.  
> > 
> > 	awk 'statement ; . . . ' file
> > 
> > be sure and use single quotes!   Lots of awk characters have
> > special meaning to the shell.  The following prints the uids in
> > the password file from highest to lowest:
> > 
> > 	awk -F: '{ print $3 }' | sort -n -r
> 
> I bet it sits there forever more because of missing input,
> 
	Right! . . . and then I go . . . "oops" and type

 	awk -F: '{ print $3 }' /etc/passwd | sort -n -r

-- 
scc!steiny
Don Steiny @ Don Steiny Software 
109 Torrey Pine Terrace
Santa Cruz, Calif. 95060
(408) 425-0382

pedz@bobkat.UUCP (Pedz Thing) (09/24/86)

In article <7759@lanl.ARPA> dph@a.UUCP (David P Huelsbeck) writes:
>This is a special case but an important one. Using the -F<c> option sets the
>field separator to the character <c>. This is important because setting the
>field separator with:
>
>	awk '{ print $3 }' FS=\":\" | sort -n -r
>
>will not set the FS variable to ":". (at least on 4.2) I haven't checked but
>I suspect that it's caused by the fact that parameter values passed from the 
>command line are not made available until after the first record has been read
>and parsed. Other variables not used in parsing (such as OFS etc.) may be set
>in the way I've shown. In the case of RS I know of no way to set it from the
>command line.
>
>	dph@lanl.arpa


Try: awk 'BEGIN { FS=":" } { print $3 }' | sort -n -r

It works Wonders.  (Not to mention that the FS="... is a pattern in
this case and not a statement.)

The is the end of the article I intended on posting but inews has the
stupic feature that no article can have few original lines than quoted
lines.  In fact Pnews seems to have an additional feature of continual
harassment whenever you try to post an article with it.  I hate stupid
things like this.  They only provoke other stupid acts like this one
of posting more garbage to the net than before.  This is almost as
dumb as the attempt to force net.announce to be shipped to all sites
by rn refusing to work without it.  Even if net.announce is shipped
between sites (all sites) that is no guarantee that it will be read.
-- 
Perry Smith
ctvax ---\
megamax --- bobkat!pedz
pollux---/