Setting awk variables via a program

Larry Wall lwall at jpl-devvax.JPL.NASA.GOV
Wed Feb 20 08:27:55 AEST 1991


In article <2391 at travis.csd.harris.com> brad at SSD.CSD.HARRIS.COM (Brad Appleton) writes:
: I have a program (much more sophisticated than getopt) that will parse
: command line arguments for sh, ksh, csh, tcsh, and bash.

: Now I would like to do a similar thing for awk-scripts. For the shell(s),
: parseargs outputs variable settings which must then be evaluated using
: `.' (or `source' or possibly `eval').  Should it do the same type of thing
: for awk? Can awk do that?

Not very easily.  awk doesn't have eval.  Your best bet would be to have
your first awk script write a second awk script that does the actual work.

: Oh yeah - since PERL is the next logical target, Id appreciate comments on
: how to do this for PERL as well!
: 
: And before you go off saying awk/perl are sophisticated enough to do this by
: themselves without too much trouble, let me just add that my program is rather
: sophisticated as well and does a bit more than just parse the command-line in
: the usual fashion.

Perl is sophisticated enough to do this by itself without too much trouble.

However, if you're very attached to your parseargs program, a wooden
translation of your sh script would look like this:

#!/usr/bin/perl
#	test.pl - Perl script to test out the parseargs command!
#
#  usage: test.pl [-d directory] [-f file [file ...]] [-x] [-y]
#                 name [arguments ...]
#
($NAME = $0) =~ s#.*/##;

$ENV{'ARGUMENTS'}="
  '?', ARGHIDDEN, argUsage, NULL,    'Help : print usage and exit',
  'd', ARGOPT,    argStr,   dirname, 'DIRectory : working directory',
  'x', ARGOPT,    argBool,  xflag,   'Xflag : turn on X-mode',
  'y', ARGOPT,    argUBool, yflag,   'Yflag : turn off Y-mode',
  'f', ARGLIST,   argStr,   files,   'files : files to process',
  ' ', ARGREQ,    argStr,   name,    'name : name to use',
  ' ', ARGLIST,   argStr,   -- ,     'argv : any remaining arguments',
  ENDOFARGS
";

$yflag='TRUE';     ## set defaults ($dir=".")

   ## parse command-line and save assignments in a temporary file ##
open(PIPE, "-|") ||
    exec 'parseargs', '-s', 'sh', '-e', 'ARGUMENTS', '-u', '--', $NAME, @ARGV;

    ## evaluate results from parseargs, translating foo= and set to Perlese
while (<PIPE>) {
    $_ .= <PIPE> while s/\\\n$//;
    &eval if s/^(\w+=)/\$$1/;
    &eval if s/^set (.*)/\@ARGV = split(' ',<<'EndOfArgs');\n$1\nEndOfArgs/;
    $stuff .= $_;
}
&eval;

sub eval { eval $stuff; $stuff = ''; }

close PIPE;
exit 2 if $?;  ## non-zero status (usage given)

   ## echo  the parsed arguments (use defaults if not defined)

$count = -1 unless defined $count;
$dirname = '.' unless defined $dirname;

print <<"EndOfText";
ARGUMENTS:
==========
Name='$name', Count='$count'
XFlag='$xflag', YFlag='$yflag'
Directory='$dirname'
Files='$files'
New Positional Parameters='@ARGV'
EndOfText
----------------------------------------------------------------------------

Or something like that.  I can't test it without your program, since I don't
know what the output of parseargs looks like.  In particular, I haven't
tried to handle any quoting on the set command that parseargs apparently
produces.

I'd still be inclined to write parseargs as a Perl subroutine.  Of course,
I'm a wee bit biased...

Larry Wall
lwall at jpl-devvax.jpl.nasa.gov



More information about the Comp.unix.questions mailing list