Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utgpu!water!watmath!clyde!rutgers!husc6!cmcl2!brl-adm!umd5!mimsy!chris From: chris@mimsy.UUCP Newsgroups: comp.unix.questions Subject: Re: executable awk scripts Message-ID: <8612@mimsy.UUCP> Date: Wed, 16-Sep-87 22:56:00 EDT Article-I.D.: mimsy.8612 Posted: Wed Sep 16 22:56:00 1987 Date-Received: Sat, 19-Sep-87 08:34:29 EDT References: <1881@vax135.UUCP> Distribution: na Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 62 In article <1881@vax135.UUCP> whb@vax135.UUCP (Wilson H. Bent) writes: >Given that these files are executable [by his 4.2BSD-based test >systems], why does this fail: > > #!/bin/awk > { print $1 } > >when this works: > > #!/bin/sh > /bin/awk '{ print $1 }' The two are not equivalent. The former runs /bin/awk with argv[1] set to the path name of the executable file (the awk script) and argv[2] through argv[n] as the `regular' argument list. The latter runs /bin/sh with argv[1] set to the path name of the executable (the shell script) and argv[2] .. argv[n] as the `regular' list. Assuming there were no other arguments, this makes argv[2] nil (or, if you prefer, (char *)0). In the first version, awk takes this argv[1] and attempts to parse it as a program: `syntax error near line 1'. In the second version, the shell takes this argv[1] and interprets it. It runs /bin/awk, this time with argv[1] being the string `{ print $1 }'. The shell does the proper thing because it assumes that, unless otherwise specified via flags, an argument names a file that is to be run. Awk fails because it assumes that, unless otherwise specified via flags, an argument is a literal awk program. Fortunately, it takes only one flag (`-f') to override this: #! /bin/awk -f { print $1 } Since one is allowed only one argument, this also works: #! /bin/awk NR > 1 { print $1 } except that it does something else entirely. Here awk's argv[1] is the string `NR > 1 { print $1 }' which is a valid awk program, and, if there were no other arguments, would be applied to stdin. There is at least one other argument: argv[2] is the name of the awk file. This makes awk print the first word of all but the first line of the file---much like `tail +2'. Awk, however, can read multiple files: #! /bin/awk NR > 1 { print } Heading that goes at the front of some sort of special report format. Running this executable and naming all the files that list the format concatenate this heading and the other files. If this is in a file called `addhead', running `addhead foo bar baz' prints the four heading lines above, followed by the contents of file foo, then bar, then baz. Note that no lines of foo, bar, or baz are skipped as NR is not reset when awk changes files. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris