Awk is a text processing language named named after the initials of its authors, Aho, Weinberger, Kernighan.
Awk is a standard program on most (all?) Unix-like operating systems.
Awk's ability to scan through a file and manipulate the contents predates Perl's functions to do this, and frankly awk's abilities, while cruder in many ways, are also simpler (simpler even than Tcl!).
Tcl is a good candidate for any tasks that might be programmed in Awk, but is a more general language, and in terms of sheer speed, is outperformed by Awk at many text processing and data extraction tasks. Core team member Alexandre Ferrieux is interested in erasing this performance difference, so maybe that will change.
LV: Awk is one of my favorite languages in which to write...
LV: A common question is:
How can I invoke awk scripts from Tcl?
Here is how not to do it:
$ tclsh % set a [exec awk {'{print $1}'} /etc/motd] awk: cmd. line:1: '{print $1}' awk: cmd. line:1: ^ invalid char ''' in expression
RS answers: This is not an Awk problem, but improper shell quoting: single quotes in a shell have the effect as braces in Tcl - group in one word, don't substitute on contents. Solution here: You have outer braces already, so just drop the single quotes (the inner brace pair is awk syntax, not seen by Tcl):
% set a [exec awk {{print $1}} /etc/motd]
RS 2007-02-07: I love this few-liner that allows tests in a subset of Awk notation (in fact, the common subset of Awk and expr, plus a shortcut for regexp):
proc awktest {filter 0} { if {[regexp {^/(.+)/$} $filter -> re]} {return [regexp $re $0]} set i 0 foreach field $0 {set [incr i] $field} expr $filter }
e.g.:
awktest {$1==$2} {foo bar grill} ;#-> 0.
$0 is just the input list :^) The following shortcut is also cute:
interp alias {} ~ {} regexp
RS 2007-11-08: When porting Awk scripts, it's also helpful to have the numbered variables:
proc awksplit {list sep} { set i 0 foreach field [split $list $sep] {uplevel 1 [list set [incr i] $field]} upvar 1 [list set NF $i] }
where for example awksplit {foo;bar;grill} {;} assigns foo to $1, bar to $2, grill to $3.
RS 2007-02-28: Here's another piece of awk emulation:
proc substr {str from length} { string range $str [expr {$from-1}] [expr {$from-2+$length}] }
% substr hello 2 2 el % substr hello 2 99 ello
And this is trivial, but over 50% shorter to type:
interp alias {} length {} string length
SW 2020-11-29: I've written tawk , an awk clone that uses tcl instead.
$ awk '{ print $1 }' input.txt $ tawk 'line { print $F(1) }' input.txt