I have awk
script doing some processing and sending it\'s output to a file.
How would I writeout in BEGIN block of my awk
program a banner-like mes
The simple way is to use a heredoc and save it in an awk variable:
VAR="whatever"
awk -v var="\
#########################################
# generated by some author #
# $VAR
#########################################" '
BEGIN{ print var }
'
#########################################
# generated by some author #
# whatever
#########################################
Alternatively, this may be more than you wanted, but below is the command I use to provide something a bit better than just here docs in awk. I find it absolutely invaluable when adding template text to multiple files..
It's a shell script which takes an awk script with slightly extended syntax (to facilitate here documents) as input, invokes gawk to transform that extended syntax to normal awk print statements, and then calls gawk again to execute the resulting script.
I call it "epawk" for "extended print" awk and what follows is the tool plus several examples of how to use it. When you invoke it instead of invoking awk directly you can write scripts that include blocks of pre-formatted text for printing like you'd want to with a here-doc (the space before each #
is a tab character):
$ export VAR="whatever"
$ epawk 'BEGIN {
print <<-!
#########################################
# generated by some author #
# "ENVIRON["VAR"]"
#########################################
!
}'
#########################################
# generated by some author #
# whatever
#########################################
It works by creating an awk script from your awk script and then executing it. If you'd just like to see the script that is being generated, epawk
will print the generated script instead of executing it if you give it the -X
argument, e.g.:
$ epawk -X 'BEGIN {
print <<-!
#########################################
# generated by some author #
# "ENVIRON["VAR"]"
#########################################
!
}'
BEGIN {
print "#########################################"
print "# generated by some author #"
print "# "ENVIRON["VAR"]""
print "#########################################"
}
THE SCRIPT:
#!/bin/bash
# The above must be the first line of this script as bash or zsh is
# required for the shell array reference syntax used in this script.
##########################################################
# Extended Print AWK
#
# Allows printing of pre-formatted blocks of multi-line text in awk scripts.
#
# Before invoking the tool, do the following IN ORDER:
#
# 1) Start each block of pre-formatted text in your script with
# print << TERMINATOR
# on it's own line and end it with
# TERMINATOR
# on it's own line. TERMINATOR can be any sequence of non-blank characters
# you like. Spaces are allowed around the symbols but are not required.
# If << is followed by -, e.g.:
# print <<- TERMINATOR
# then all leading tabs are removed from the block of pre-formatted
# text (just like shell here documents), if it's followed by + instead, e.g.:
# print <<+ TERMINATOR
# then however many leading tabs are common across all non-blank lines
# in the current pre-formatted block are removed.
# If << is followed by =, e.g.
# print <<= TERMINATOR
# then whatever leading white space (tabs or blanks) occurs before the
# "print" command will be removed from all non-blank lines in
# the current pre-formatted block.
# By default no leading spaces are removed. Anything you place after
# the TERMINATOR will be reproduced as-is after every line in the
# post-processed script, so this for example:
# print << HERE |"cat>&2"
# foo
# HERE
# would cause "foo" to be printed to stderr.
#
# 2) Within each block of pre-formatted text only:
# a) Put a backslash character before every backslash (\ -> \\).
# b) Put a backslash character before every double quote (" -> \").
# c) Enclose awk variables in double quotes without leading
# backslashes (awkVar -> "awkVar").
# d) Enclose awk record and field references ($0, $1, $2, etc.)
# in double quotes without leading backslashes ($1 -> "$1").
#
# 3) If the script is specified on the command line instead of via
# "-f script" then replace all single quote characters (') in or out
# of the pre-formatted blocks with their ANSI octal escape sequence (\047)
# or the sequence '\'' (tick backslash tick tick). This is normal and is
# required because command-line awk scripts cannot contain single quote
# characters as those delimit the script. Do not use hex \x27, see
# http://awk.freeshell.org/PrintASingleQuote.
#
# Then just use it like you would gawk with the small caveat that only
# "-W
USAGE EXAMPLES:
$ cat data.txt
abc def"ghi
.
#######
$ cat script.awk
{
awkVar="bar"
print "----------------"
print << HERE
backslash: \\
quoted text: \"text\"
single quote as ANSI sequence: \047
literal single quote (ONLY works when script is in a file): '
awk variable: "awkVar"
awk field: "$2"
HERE
print "----------------"
print <<-!
backslash: \\
quoted text: \"text\"
single quote as ANSI sequence: \047
literal single quote (ONLY works when script is in a file): '
awk variable: "awkVar"
awk field: "$2"
!
print "----------------"
print <<+ whatever
backslash: \\
quoted text: \"text\"
single quote as ANSI sequence: \047
literal single quote (ONLY works when script is in a file): '
awk variable: "awkVar"
awk field: "$2"
whatever
print "----------------"
}
.
$ epawk -f script.awk data.txt
----------------
backslash: \
quoted text: "text"
single quote as ANSI sequence: '
literal single quote (ONLY works when script is in a file): '
awk variable: bar
awk field: def"ghi
----------------
backslash: \
quoted text: "text"
single quote as ANSI sequence: '
literal single quote (ONLY works when script is in a file): '
awk variable: bar
awk field: def"ghi
----------------
backslash: \
quoted text: "text"
single quote as ANSI sequence: '
literal single quote (ONLY works when script is in a file): '
awk variable: bar
awk field: def"ghi
----------------
.
$ epawk -F\" '{
print <
.
epawk -F\" '{
print <
.
$ epawk -F\" '{
print <
.
$ epawk -X 'BEGIN{
print <
.
$ cat file
a
b
c
.
$ epawk '{
print <<+! |"cat>o2"
numLines="NR"
numFields="NF", $0="$0", $1="$1"
!
}' file
.
$ cat o2
numLines=1
numFields=1, $0=a, $1=a
numLines=2
numFields=1, $0=b, $1=b
numLines=3
numFields=1, $0=c, $1=c
.
$ epawk 'BEGIN{
cmd = "sort"
print <<+! |& cmd
d
b
a
c
!
close(cmd, "to")
while ( (cmd |& getline line) > 0 ) {
print "got:", line
}
close(cmd)
}' file
got: a
got: b
got: c
got: d