.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "runawk 1" .TH runawk 1 "2016-02-29" "" "" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" runawk \- wrapper for AWK interpreter .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fBrunawk\fR \fI[options]\fR \fIprogram_file\fR .PP \&\fBrunawk\fR \fI\-e\fR \fIprogram\fR .SH "MOTIVATION" .IX Header "MOTIVATION" After years of using \s-1AWK\s0 for programming I've found that despite of its simplicity and limitations \s-1AWK\s0 is good enough for scripting a wide range of different tasks. \s-1AWK\s0 is not as poweful as their bigger counterparts like Perl, Ruby, \s-1TCL\s0 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 techniques for text processing utilities. .PP Unfortunately awk interpreters lacks some important features and sometimes do not work as good as they could do. .PP Problems I see (some of them, of course) .IP "1." 2 \&\s-1AWK\s0 lacks support for modules. Even if I create small programs, I often want to use functions created earlier and already used in other scripts. That is, it whould great to organise functions into so called libraries (modules). .IP "2." 2 In order to pass arguments to \f(CW\*(C`#!/usr/bin/awk \-f\*(C'\fR script (not to awk interpreter), it is necessary to prepend a list of arguments with \*(-- (two minus signes). In my view, this looks badly. Also such behaviour violates \s-1POSIX/SUS \s0\*(L"Utility Syntax Guidelines\*(R". .Sp Example: .Sp awk_program: .Sp .Vb 1 \& #!/usr/bin/awk \-f \& \& BEGIN { \& for (i=1; i < ARGC; ++i){ \& printf "ARGV [%d]=%s\en", i, ARGV [i] \& } \& } .Ve .Sp Shell session: .Sp .Vb 2 \& % 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 \& % .Ve .Sp In my opinion \fIawk_program\fR script should work like this .Sp .Vb 4 \& % awk_program \-\-opt1 \-\-opt2 \& ARGV [1]=\-\-opt1 \& ARGV [2]=\-\-opt2 \& % .Ve .IP "3." 2 When \f(CW\*(C`#!/usr/bin/awk \-f\*(C'\fR script handles arguments (options) and wants to read from stdin, it is necessary to add /dev/stdin (or `\-') as a last argument explicitly. .Sp Example: .Sp awk_program: .Sp .Vb 1 \& #!/usr/bin/awk \-f \& \& BEGIN { \& if (ARGV [1] == "\-\-flag"){ \& flag = 1 \& ARGV [1] = "" # to not read file named "\-\-flag" \& } \& } \& \& { \& print "flag=" flag " $0=" $0 \& } .Ve .Sp Shell session: .Sp .Vb 4 \& % echo test | awk_program \-\- \-\-flag \& % echo test | awk_program \-\- \-\-flag /dev/stdin \& flag=1 $0=test \& % .Ve .Sp Ideally \fIawk_program\fR should work like this .Sp .Vb 3 \& % echo test | awk_program \-\-flag \& flag=1 $0=test \& % .Ve .IP "4." 2 \&\fIigawk\fR\|(1) which is shipped with \s-1GNU\s0 awk can not be used in shebang. On most (all?) UNIXes scripts beginning with .Sp .Vb 1 \& #!/usr/local/bin/igawk \-f .Ve .Sp will not work. .PP \&\fBrunawk\fR was created to solve all these problems .SH "OPTIONS" .IX Header "OPTIONS" .IP "\fB\-d\fR" 6 .IX Item "-d" Turn on a debugging mode. .IP "\fB\-e\fR \fIprogram\fR" 6 .IX Item "-e program" Specify program. If \fI\-e\fR is not specified, the \s-1AWK\s0 code is read from \&\fIprogram_file\fR. .IP "\fB\-f\fR \fIawk_module\fR" 6 .IX Item "-f awk_module" Activate \fIawk_module\fR. This works the same way as .Sp .Vb 1 \& #use "awk_module.awk" .Ve .Sp directive in the code. Multiple \fB\-f\fR options are allowed. .IP "\fB\-F\fR \fIfs\fR" 6 .IX Item "-F fs" Set the input field separator \s-1FS\s0 to the regular expression \fIfs\fR. .IP "\fB\-h\fR" 6 .IX Item "-h" Display help information. .IP "\fB\-t\fR" 6 .IX Item "-t" If this option is applied, a temporary directory is created by \&\fBrunawk\fR and path to it is passed to \fBawk\fR child process. Temporary directory is created under ${\s-1RUNAWK_TMPDIR\s0} (if it is set), or ${\s-1TMPDIR\s0} (if it is set) or /tmp directory otherwise. If \fI#use \*(L"tmpfile.awk\*(R"\fR is detected in a program this option is activated automatically. .IP "\fB\-T\fR" 6 .IX Item "-T" Set \s-1FS\s0 to \s-1TAB\s0 character. This is equivalent to \fB\-F'\et'\fR .IP "\fB\-V\fR" 6 .IX Item "-V" Display version information. .IP "\fB\-v\fR \fIvar\fR=\fIval\fR" 6 .IX Item "-v var=val" Assign the value \fIval\fR to the variable \fIvar\fR before execution of the program begins. .SH "DETAILS/INTERNALS" .IX Header "DETAILS/INTERNALS" .SS "Standalone script" .IX Subsection "Standalone script" Under UNIX-like OS-es you can use \fBrunawk\fR by beginning your script with .PP .Vb 1 \& #!/usr/local/bin/runawk .Ve .PP line or something like this instead of .PP .Vb 1 \& #!/usr/bin/awk \-f .Ve .PP or similar. .SS "\s-1AWK\s0 modules" .IX Subsection "AWK modules" In order to activate modules you should add them into awk script like this .PP .Vb 2 \& #use "module1.awk" \& #use "module2.awk" .Ve .PP that is the line that specifies module name is treated as a comment line by normal \s-1AWK\s0 interpreter but is processed by \fBrunawk\fR especially. .PP Unless you run \fBrunawk\fR with option \fB\-e\fR, \fI#use\fR must begin with column 0, that is no spaces or tabs symbols are allowed before it and no symbols are allowed between \fI#\fR and \fIuse\fR. .PP Also note that \s-1AWK\s0 modules can also \*(L"use\*(R" another modules and so forth. All them are collected in a depth-first order and each one is added to the list of awk interpreter arguments prepanded with \-f option. That is \fI#use\fR directive is *NOT* similar to \fI#include\fR in C programming language, runawk's module code is not inserted into the place of \fI#use\fR. Runawk's modules are closer to Perl's \*(L"use\*(R" command. In case some module is mentioned more than once, only one \-f will be added for it, i.e duplications are removed automatically. .PP Position of \fI#use\fR directive in a source file does matter, i.e. the earlier module is mentioned, the earlier \-f will be generated for it. .PP Example: .PP .Vb 2 \& file prog: \& #!/usr/local/bin/runawk \& \& #use "A.awk" \& #use "B.awk" \& #use "E.awk" \& \& PROG code \& ... \& \& file B.awk: \& #use "A.awk" \& #use "C.awk" \& B code \& ... \& \& file C.awk: \& #use "A.awk" \& #use "D.awk" \& \& C code \& ... \& \& A.awk and D.awk don\*(Aqt contain #use directive .Ve .PP If you run .PP .Vb 1 \& runawk prog file1 file2 .Ve .PP or .PP .Vb 1 \& /path/to/prog file1 file2 .Ve .PP the following command .PP .Vb 1 \& awk \-f A.awk \-f D.awk \-f C.awk \-f B.awk \-f E.awk \-f prog \-\- file1 file2 .Ve .PP will actually run. .PP You can check this by running .PP .Vb 1 \& runawk \-d prog file1 file2 .Ve .SS "Module search strategy" .IX Subsection "Module search strategy" Modules are first searched in a directory where main program (or module in which #use directive is specified) is placed. If it is not found there, then \&\s-1AWKPATH\s0 environment variable is checked. \s-1AWKPATH\s0 keeps a colon separated list of search directories. Finally, module is searched in system runawk modules directory, by default PREFIX/share/runawk but this can be changed at compile time. .PP An absolute path to the module can also be specified. .SS "Program as an argument" .IX Subsection "Program as an argument" Like some other interpreters \&\fBrunawk\fR can obtain the script from a command line like this .PP .Vb 2 \& /path/to/runawk \-e \*(Aq \& #use "alt_assert.awk" \& \& { \& assert($1 >= 0 && $1 <= 10, "Bad value: " $1) \& \& # your code below \& ... \& }\*(Aq .Ve .PP \&\fBrunawk\fR can also be used for writing oneliners .PP .Vb 1 \& runawk \-f abs.awk \-e \*(AqBEGIN {print abs(\-1)}\*(Aq .Ve .SS "Selecting a preferred \s-1AWK\s0 interpreter" .IX Subsection "Selecting a preferred AWK interpreter" For some reason you may prefer one \s-1AWK\s0 interpreter or another. The reason may be efficiency for a particular task, useful but not standard extensions or enything else. To tell \fBrunawk\fR what \s-1AWK\s0 interpreter to use, one can use \fI#interp\fR directive .PP .Vb 2 \& file prog: \& #!/usr/local/bin/runawk \& \& #use "A.awk" \& #use "B.awk" \& \& #interp "/usr/pkg/bin/nbawk" \& \& # your code here \& ... .Ve .PP Note that \fI#interp\fR directive should also begin with column 0, no spaces are allowed before it and between \fI#\fR and \fIinterp\fR. .PP Sometimes it also makes sense to give users ability to select their preferred \s-1AWK\s0 interpreter without changing the source code. In \&\fBrunawk\fR it is possible using special directive \fI#interp\-var\fR which sets an environment variable name assignable by user that specifies an \&\s-1AWK\s0 interpreter. For example, the following script .PP .Vb 2 \& file foobar: \& #!/usr/bin/env runawk \& \& #interp\-var "FOOBAR_AWK" \& \& BEGIN { \& print "This is a FooBar application" \& } .Ve .PP can be run as .PP .Vb 1 \& env FOOBAR_AWK=mawk foobar .Ve .PP or just .PP .Vb 1 \& foobar .Ve .PP In the former case \fBmawk\fR will be used as \s-1AWK\s0 interpreter, in the latter \*(-- the default \s-1AWK\s0 interpreter. .SS "Using existing modules only" .IX Subsection "Using existing modules only" In \s-1UNIX\s0 world it is common practise to write configuration files in a programming language of the application. That is, if application is written in Bourne shell, configuration files for such application are often written in Bourne as well. Using RunAWK one can do the same for applications written in \s-1AWK.\s0 For example, the following code will use ~/.foobarrc file if it exists otherwise /etc/foobar.conf will be used if it exists. .PP .Vb 2 \& file foobar: \& #!/usr/bin/env runawk \& \& #safe\-use "~/.foobarrc" "/etc/foobar.conf" \& \& BEGIN { \& print foo, bar, baz \& } \& \& file ~/.foobarrc: \& BEGIN { \& foo = "foo10" \& bar = "bar20" \& baz = 123 \& } .Ve .PP Of course, \fI#safe\-use\fR directive may be used for other purposes as well. \fI#safe\-use\fR directive accepts as much modules as you want, but at most one can be included using awk option \-f, others are silently ignored, also note that modules are analysed from left to right. Leading tilde in the module name is replaced with user's home directory. Another example: .PP .Vb 2 \& file foobar: \& #!/usr/bin/env runawk \& \& #use "/usr/share/foobar/default.conf" \& #safe\-use "~/.foobarrc" "/etc/foobar.conf" \& \& your code is here .Ve .PP Here the default settings are set in /usr/share/foobar/default.conf, and configuration files (if any) are used for overriding them. .SS "Setting environment" .IX Subsection "Setting environment" In some cases you may want to run \s-1AWK\s0 interpreter with a specific environment. For example, your script may be oriented to process \s-1ASCII\s0 text only. In this case you can run \s-1AWK\s0 with LC_CTYPE=C environment and use regexp ranges. .PP \&\fBrunawk\fR provides \fI#env\fR directive for this. String inside double quotes is passed to \fIputenv\fR\|(3) libc function. .PP Example: .PP .Vb 2 \& file prog: \& #!/usr/local/bin/runawk \& \& #env "LC_ALL=C" \& \& $1 ~ /^[A\-Z]+$/ { # A\-Z is valid if LC_CTYPE=C \& print $1 \& } .Ve .SH "EXIT STATUS" .IX Header "EXIT STATUS" If \s-1AWK\s0 interpreter exits normally, \fBrunawk\fR exits with its exit status. If \s-1AWK\s0 interpreter was killed by signal, \fBrunawk\fR exits with exit status 128+signal. .SH "ENVIRONMENT" .IX Header "ENVIRONMENT" .IP "\fI\s-1AWKPATH\s0\fR" 6 .IX Item "AWKPATH" Colon separated list of directories where \fBawk\fR modules are searched. .IP "\fI\s-1RUNAWK_AWKPROG\s0\fR" 6 .IX Item "RUNAWK_AWKPROG" Sets the path to the \s-1AWK\s0 interpreter, used by default, i.e. this variable overrides the compile-time default. Note that #interp directive overrides this. .IP "\fI\s-1RUNAWK_KEEPTMP\s0\fR" 6 .IX Item "RUNAWK_KEEPTMP" If set, temporary files are not deleted. .SH "AUTHOR" .IX Header "AUTHOR" Copyright (c) 2007\-2014 Aleksey Cheusov .SH "BUGS/FEEDBACK" .IX Header "BUGS/FEEDBACK" Please send any comments, questions, bug reports etc. to me by e\-mail or register them at sourceforge project home. Feature requests are also welcomed. .SH "HOME" .IX Header "HOME" .SH "SEE ALSO \fIawk\fP\|(1)" .IX Header "SEE ALSO awk"