runawk is a tiny wrapper for AWK interpreter that impements module system and helps to write the standalone AWK programs.
MOTIVATION
After years of using AWK for programming I've found that despite of
its simplicity and limitations AWK is good enough for scripting a wide
range of different tasks. AWK is not as poweful as their bigger
counterparts like Perl, Ruby, TCL and others but it has their own
advantages like compactness, simplicity and availability on almost all
UNIX-like systems. I personally also like its data-driven nature and
token orientation, very useful technique for simple text processing
utilities.
But! Unfortunately awk interpreters lacks some important features and
sometimes work not as good as it whould be.
Some problems I see (some of them, of course).
1) AWK lacks support for modules. Even if I create small programs, I
often want to use the functions created earlier and already used in
other scripts. That is, it whould great to orginise functions into
so called libraries (modules).
2) In order to pass arguments to #!/usr/bin/awk -f script (not to awk
interpreter), it is necessary to prepand a list of
arguments with -- (two minus signes). In my view, this looks badly.
Example:
awk_program:
#!/usr/bin/awk -f
BEGIN {
for (i=1; i < ARGC; i){
printf "ARGV [%d]=%s ", i, ARGV [i]
}
}
Shell session:
% awk_program --opt1 --opt2
/usr/bin/awk: unknown option --opt1 ignored
/usr/bin/awk: unknown option --opt2 ignored
% awk_program -- --opt1 --opt2
ARGV [1]=--opt1
ARGV [2]=--opt2
%
In my opinion awk_program script should work like this (just like
normal programs do)
% awk_program --opt1 --opt2
ARGV [1]=--opt1
ARGV [2]=--opt2
%
It is possible using runawk.
3) When #!/usr/bin/awk -f script handles arguments (options) and wants
to read from stdin, it is necessary to add
/dev/stdin (or `-') as a last argument explicitely.
Example:
awk_program:
#!/usr/bin/awk -f
BEGIN {
if (ARGV [1] == "--flag"){
flag = 1
ARGV [1] = "" # to not read file named "--flag"
}
}
{
print "flag=" flag " $0=" $0
}
Shell session:
% echo test | awk_program -- --flag
% echo test | awk_program -- --flag /dev/stdin
flag=1 $0=test
%
Ideally awk_program should work like this
% echo test | awk_program --flag
flag=1 $0=test
%
All these probles are solved by runawk and this is why I wrote it.
I also include a few modules to runawk distribution which are
useful for me and I hope will be helpful for you too.
INSTALLATION
0) BSD make is required. I name it just 'make' but its real name may
vary. bmake and pmake are possible names.
If you need to change the default building options,
run make like this
env [YOUR_ASSIGNMENTS] make < target >
See example section below
1) Uncompress tarball you've downloaded like this
gzip -dc runawk-X-Y-Z.tar.gz | tar -xf-
2) cd runawk-X-Y-Z
3) make
4) (optional!) make install-dirs
5) make install
There are a lot of Makefile variables that can be changed during
installation. Runawk's own variables (All they are at the begining of
Makefile):
PREFIX - where runawk is installed to
MODULESDIR - directory where modules are installed to
AWK_PROG - path to awk interpreter
STDIN_FILENAME - path to stdin device file
BSD make's variables (most commonly used,
for all others - see make's documentation and .mk files)
BINDIR - where runawk executable itself is installed to
MANDIR - where manual pages are installed to
BINOWN - runawk executable owner
BINGRP - runawk executable group
MANOWN - man page owner
MANGRP - man page group
Example:
env CC=gcc
PREFIX=/home/cheusov/local
LDFLAGS='-L/usr/pkg/lib -Wl,-rpath -Wl,/usr/pkg/lib'
LDADD=-lextralib
CFLAGS='-Werror -Wall'
CPPFLAGS=-I/usr/pkg/include
BINOWN=cheusov
BINGRP=users
MANOWN=cheusov
MANGRP=users
MKCATPAGES=no
make -s all install-dirs install
What's New in This Release: [ read full changelog ]
· In exitnow.awk, the exitnow(status) function now finishes the execution of the script without running END sections even if status == 0.
· The new module io.awk includes the functions is_{file,dir,exec,socket,fifo,blockdev,chardev,symlink}, file_size, and file_type. tokenre.awk has the new function splitre0().