2

Gawk 5.0.0 was released on April 12, 2019. Going through the announcement I found this:

Changes from 4.2.1 to 5.0.0

(...) 11. Namespaces have been implemented! See the manual. One consequence of this is that files included with -i, read with -f, and command line program segments must all be self-contained syntactic units. E.g., you can no longer do something like this:

gawk -e 'BEGIN {' -e 'print "hello" }'

I was curious about this behaviour that is no longer supported, but unfortunately my Gawk 4.1.3 did not offer much output out of it:

$ gawk -e 'BEGIN {' -e 'print "hello" }'
gawk: cmd. line:1: BEGIN {
gawk: cmd. line:1:        ^ unexpected newline or end of string

From what I see in the manual of GAWK 4.2, the -e option was marked as problematic already:

GNU Awk User's Guide, on Options

-e program-text
--source program-text

Provide program source code in the program-text. This option allows you to mix source code in files with source code that you enter on the command line. This is particularly useful when you have library functions that you want to use from your command-line programs (see AWKPATH Variable).

Note that gawk treats each string as if it ended with a newline character (even if it doesn’t). This makes building the total program easier.

CAUTION: At the moment, there is no requirement that each program-text be a full syntactic unit. I.e., the following currently works:

$ gawk -e 'BEGIN { a = 5 ;' -e 'print a }'
-| 5

However, this could change in the future, so it’s not a good idea to rely upon this feature.

But, again, this fails in my console:

$ gawk -e 'BEGIN {a=5; ' -e 'print a }'
gawk: cmd. line:1: BEGIN {a=5; 
gawk: cmd. line:1:             ^ unexpected newline or end of string

So what is gawk -e 'BEGIN {' -e 'print "hello" }' doing exactly on Gawk < 5?

fedorqui
  • 275,237
  • 103
  • 548
  • 598
  • I've tested this with 4.2.1 and it works as expected. A simple concatenation of all `-e` strings separated by newlines. It does not work with 4.0.2 – kvantour Apr 16 '19 at 08:07
  • @kvantour ah right, then Ed's answer nails it. Thanks for checking it out with a Gawk 4.2! – fedorqui Apr 16 '19 at 08:28
  • I'm digging through the code to see what could have changed, but I cannot find it. – kvantour Apr 16 '19 at 08:36
  • @kvantour indeed. Going through the [Gawk 4.2.0 announcement](https://lists.gnu.org/archive/html/info-gnu/2017-10/msg00004.html) I could not find any reference to `e`. – fedorqui Apr 16 '19 at 08:44
  • 2
    @kvantour I found the [docs of Gawk 4.1](https://web.archive.org/web/20171002212822/https://www.gnu.org/software/gawk/manual/gawk.html) and I see that `--source` just had the first paragraph, so this part is new: _Note that gawk treats each string as if it ended with a newline character (even if it doesn’t). This makes building the total program easier_. – fedorqui Apr 16 '19 at 08:54

1 Answers1

3

It's doing just what you'd expect - concatenating the parts to form gawk 'BEGIN {print "hello" }' and then executing it. You can actually see how gawk is combining the code segments by pretty-printing it:

$ gawk -o- -e 'BEGIN {' -e 'print "hello" }'
BEGIN {
        print "hello"
}

That script isn't useful to be written in sections and concatenated but if you consider something like:

$ cat usea.awk
{ a++ }

$ echo foo | gawk -e 'BEGIN{a=5}' -f usea.awk -e 'END{print a}'
6

then you can see the intended functionality might be useful for mixing some command-line code with scripts stored in files to run:

$ gawk -o- -e 'BEGIN{a=5}' -f usea.awk -e 'END{print a}'
BEGIN {
        a = 5
}

{
        a++
}

END {
        print a
}
Ed Morton
  • 188,023
  • 17
  • 78
  • 185
  • Thanks! Interesting to see that this works fine on Gawk 4.2 but it does not in 4.1, the one I was using. – fedorqui Apr 16 '19 at 08:51
  • Cool! I didn't know about the -o / --pretty-print option – fedorqui Apr 16 '19 at 13:20
  • It's extremely useful to help understand many of the scripts we see posted because we get some VERY interesting ideas wrt code layout in this forum! – Ed Morton Apr 16 '19 at 13:21
  • 2
    I could not refrain from posting a question to explain that the `-o` option exists! [Is it possible to pretty print Awk's code?](https://stackoverflow.com/q/55745956/1983854) – fedorqui Apr 18 '19 at 12:23