brad@SSD.CSD.HARRIS.COM (Brad Appleton) (02/20/91)
I have a program (much more sophisticated than getopt) that will parse command line arguments for sh, ksh, csh, tcsh, and bash. I would like to be able to use it for awk as well. When I use it for the bourne-shell, it looks something like: ---------------------------------------------------------------------------- #!/bin/sh # test.sh - Bourne shell script to test out the parseargs command! # # usage: test.sh [-d directory] [-f file [file ...]] [-x] [-y] # name [arguments ...] # NAME="`basename $0`"; 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 " export ARGUMENTS yflag='TRUE' ## set defaults (dir=".") ## parse command-line and save assignments in a temporary file ## parseargs -s sh -e ARGUMENTS -u -- "$NAME" "$@" >/tmp/tmp$$ if [ $? -ne 0 ] then rm -f /tmp/tmp$$; exit 2 ## non-zero status (usage given) fi ## evaluate results from parseargs and remove temporary file . /tmp/tmp$$; rm -f /tmp/tmp$$ ## echo the parsed arguments (use defaults if not defined) echo "ARGUMENTS:" echo "==========" echo "Name='$name', Count='${count:-1}'" echo "XFlag='$xflag', YFlag='$yflag'" echo "Directory='${dirname:-"."}'" echo "Files='$files'" echo "New Positional Parameters='$*'" ---------------------------------------------------------------------------- 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? If not, it should probably return some string that can be massaged (with as little effort as possible) to get the desired variables (and/or arrays) with the values intended on the command-line. Ive found little in "The AWK Programming Language" to help me in this endeavor. I was hoping one of you awk-guru's might be able to show me how its done. 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. Any help is greatly appreciated! ______________________ "And miles to go before I sleep." ______________________ Brad Appleton brad@ssd.csd.harris.com Harris Computer Systems uunet!hcx1!brad Fort Lauderdale, FL USA ~~~~~~~~~~~~~~~~~~~~ Disclaimer: I said it, not my company! ~~~~~~~~~~~~~~~~~~~
lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (02/20/91)
In article <2391@travis.csd.harris.com> brad@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@jpl-devvax.jpl.nasa.gov