Awk vs. Perl (2009)
aplawrence.com
aplawrence.com
Brian Kernighan himself, in this 2015 talk [1] on language design, states that Awk was primarily intended for one-liner usage (he mentions this at 20:43).
Al said that if Perl had existed first there wouldn't have been an awk. I pointed out that parts of Perl are inspired by awk and might have otherwise been inspired by SNOBOL or ICON, at which point everyone present seemed to agree means we're thankful for awk. I take it as high praise when Al Aho defers to your tool.
I was just reminiscing with Larry about that discussion last week at The Perl Conference in Arlington. He said he had fond memories of that conversation and that he and Al went for lunch the next day after that conversation, too. I'd have loved to be there for that.
awk '{print $3 ":" $1 " " $2}'
in Perl? perl -nae'printf("%s:%s %s\n",$F[2],$F[0],$F[1])' $ txr -e '(awk ((prn `@[f 2]:@[f 0] @[f 1]`)))'
1 2 3
3:1 2
How about input from a string stream? At the REPL: 1> (with-in-string-stream (*stdin* "1 2 3")
(awk ((prn `@[f 2]:@[f 0] @[f 1]`))))
3:1 2
nil
It pays not to have awk be some some canned global behavior enabled by a command line option. txr -e '(awk (:set ofs "") ((prn [f 2] ":" [f 0] " " [f 1])))'
This is like: awk -v OFS= '{print $3, ":", $1, " ", $2}' perl -aE 'say "$F[2]:$F[0] $F[1]"'It's like a very neat, small domain specific language for use processing simple record based text files. And within those limits it's super useful.
Not exactly only simple processing, IMO. Record processing, yes - it is a domain specific language, and its core feature is the pattern-action thing, and it was (at least originally) meant mainly to operate on record-oriented text files (even if on lines, since a line is a record with one column). I don't have good examples off the top of my head, but can mention a few things:
The books The Unix Programming Environment by Kernighan and Pike, and either Programming Pearls or More Programming Pearls, by Jon Bentley, have some examples of advanced uses of awk - so it is not just for simple record processing. And I've read somewhere that just shell and awk and other Unix tools have even been used to create a DBMS of sorts. Plus, with later versions like GNU awk and so on, they've added more features to the language, including probably many more built-in functions, and also some network programming support [1].
https://www.quora.com/What-is-the-most-complex-software-writ...
According to an answer at the above link, an nroff-subset text formatter and Lisp subset interpreter have been written in awk. Those are more complex than simple record processing.
Also:
[1] Effective awk Programming, 3rd Edition http://shop.oreilly.com/product/9780596000707.do
U have been reading "The AWK programming language" and actually kinda fell in love with awk.
Awk does many simple things, it's fairly nice to combine such simple things, and it's generally a nice and handy tool to know.
Yep, it's totally useless and is really only designed to draw ad traffic (god there's a lot of ads)
Obviously, the two languages overlap in functionality, and the one you know is going to be easier for the job (for you).
If you know neither, Awk is easier to learn, but that's of course because it does less. That may be good or bad, depending on what you are trying to do.
And despite having a strong affinity for Perl, I don't think it's productive to just bannish Awk to the trash: part of being well-rounded is knowing many tools—which can overlap to some degree—and appreciating the sweet spot of each one. For some one-liners, Awk is just as (if not more) elegant as Perl.
awk '$4 ~ /T/ { print $1 }'
perl -nE '@x = split /\s+/; say $x[0] if $x[3] =~ /T/;'
... stares at this and wonders ... reads `man perlrun` ... Oooh, there's a switch to auto-split-on-whitespace in Perl. perl -anE 'say $F[0] if $F[3] =~ /T/;'
Sooo this doesn't quite answer your question anymore, but I'm going to leave this here since it's a nice instance of TIL.-a implicitly sets -n.
That and maybe because i'm an old perl die hard, its just easier to pipe to perl than remember how awk does its shenanigans.
The nice thing about the @F array is that @F[0] doesn't represent the whole record.
There is a class of Awk bugs whereby arithmetic is being done on the parameters using $N (where N is some calculated variable containing an integer). Everything is fine when N >= 1, but if there is a bug where N is accidentally zero, then $N refers to the whole record instead of throwing an out-of-bounds error.
And things are accidentally zero quite easily in awk, e.g.
awk '{print $X}' # X is undefined so serves as zero; this prints all linesHowever, on the same OS, "nawk" does.
I've long since had to deal with Solaris but for about 10 years of Solaris I always treat awk with a lowest common denominator approach. Which means I tend to avoid it even to this day.
txr -e '(awk ([#/T/ [f 3]] (prn [f 0])))'
-e is just "evaluate Lisp expression for side effects; don't print its value" > perl -anE 'say $F[0] if $F[3] =~ /T/;'
^
^
Please tell me that isn't required. Fail!I dont want to invest the time in Perl, when there are better general purpose languages out there. Perl certainly has a different look, I can understand why some would love it.
My time with Perl was wrestling with code that people wrote to show how good they were at Perl, and where maintainability was a secondary concern. This is a bit harder to do in Awk (but not impossible). I moved from Perl to Python in the 1.5 days in part because of this.
I believe this occurs with Java now too. Neither Perl nor Java are bad languages, they are both powerful and performant. However there are some architecture astronauts who seem to enjoy making life harder for the rest of us.
The shell scripts I write are usually just canned commands, maybe some tweaking with environment variables. Anything more complex I usually handle using Perl.
Shell scripts supposedly are more portable because the Bourne shell is always there, but that only is true with different Unix flavours. Once you run into a Windows box, (or more exotic systems like OS/400 (whatever IBM calls it these days), VMS, z/OS, BS2000), shell scripts won't help you. Perl will. ;-)
Last but not least: CPAN. There are perl modules available for nearly anything you could ask for. (Except talking to SharePoint, which I sadly have to do on a fairly regular basis. OTOH, having known its horrors, I can understand why the Perl community wants to stay away from that POS.)
seq 1 20 | ruby -pe 'puts "num is #{$_}"'
Perl is probably a bit more concise, but you can do a lot of stuff with Ruby, which is convenient if you use it for other things too.In Awk, you can define a function like this:
function add(a, m, n,
sum)
{
for (sum = 0; m < n; m++)
sum += a[m]
return sum
}
Named parameters (wow, there is a concept); and few dermatological problems: no damn sigils, or required statement-terminating semicolons. The array reference is a[m], the scalar is m and so on.Using an extra parameter (which is not specified in the call) for the local variable sum is a massive design fail, but no worse than any of the Perl design fails.
Perl repeats most of the design flaws in Awk, with compounded interest.
The one huge thing that sed is particularly bad at (unless I don't know the particular trick yet) is to split fields on a pattern. I frequently have pipes where sed is used for most of the text-processing, but then cut is used to select one (or multiple) character-separated fields, or awk is used to select one (or multiple) whitespace-separated fields. I only go one step further (usually to Perl) when operations involve multiple lines, e.g. when columns need to be summed up.
Not much; just, oh, stuff like floating-point math and trig functions; integer math, associative arrays, access to environment variables, named functions with arguments and full recursion; control and looping structures like if, for and while, file I/O and redirection, string literals with C escapes, ...
$ awk '$0=sin($1) + cos($2)'
0 1
0.540302
1 0
1.84147
How about sed?Just kidding ...
Wrote this earlier in this same thread:
http://www.nongnu.org/txr/txr-manpage.html#N-012F3A2C
POSIX standard's Awk examples, translated:
I find awk easy to understand when I read a script after not seeing it for a long time (though I have to google each time I'm writing string manipulation and use arrays) .
http://alquerubim.blogspot.com.br/2016/09/a-linha-mais-compr...
Still, awk was simpler.
Your code is verbose: length($0) shortens to just length:
awk 'length > max { max = length } END { print max }'
The Perl seems to have an off-by-one error.Still, it is good fortune that the scheduler was not written in awk.