Can you use heredocuments to embed AWK in a bash script?
Writing a shell script that pretty much wraps around an Awk script. I'd like to have my syntax colouring on in the awk section so I feel there must be a better way to embed awk scripts to bash than just quote the 开发者_Go百科script in.
Or is it the best way to develop the awk on a separate file and use awk -f
in the bash script until the script's done? I'd like to keep within one file all times!
#!/bin/bash
awkscript='
BEGIN{
print "test"
}
{print $3}'
df | awk "$awkscript"
This is the quote way, and quite ugly if you ask me. Any chance for heredocs here?
Yes, in Bash this is possible in a slightly less ugly way:
#!/bin/bash
df | awk -f <(cat - <<-'EOD'
BEGIN{
print "test"
}
{print $3}
EOD
)
The <()
code block is replaced with a path (something like /dev/fd/63
) which points to a file descriptor tied to the output of the code. Make sure the awk script is indented with tabs and not spaces (<<-
strips leading tabs).
Another way to do this is to hide the awk script at the end of the bash script like this (don't forget to exit
):
#!/bin/bash
df | awk -f <(sed -e '0,/^#!.*awk/d' $0)
exit $PIPESTATUS
#!/usr/bin/awk -f
BEGIN {
print "test"
}
{print $3}
If you don't want to use stdin for the data, do this --- it's portable, fast, and doesn't use any bashisms.
awk -f- inputfile.txt <<'EOF'
BEGIN {
print "hello world"
}
EOF
Telling awk to use an input filename of -
causes it to read the script from stdin.
Of course, you now have to store your data in a file. If you really can't do this, use a named pipe.
f=/tmp/$$.data
trap "rm -f $f" EXIT
mknod $f p
(df > $f) &
awk -f- $f <<EOF
{ print }
EOF
ugly too:
read -r -d '' awkscript <<'EOF'
BEGIN{ print "test"}
{print $3}
EOF
df | awk "$awkscript"
Not sure what you mean, but are you looking for something like this?
#!/bin/bash
awk 'BEGIN {
print "hello world"
}
{
print $3
}' <<< "$(df)"
Have a look at 3.6.7 Here Strings in the bash manual
Sometimes this may be usefull:
awkscript=$(cat << EOT
BEGIN{
print "test"
}
{print $3}
EOT
)
df | awk "$awkscript"
One way is to let awk read rules from stdin using (heredoc or here string) but process real files or files created by subprocess substitution, like this
awk -f- <(df) <<'EOF'
BEGIN{
print "test"
}
{print $3}
EOF
-f-
should appear before <(df)
. The delimiter for the heredoc should be quoted so that the $
signs will be passed into awk instead of being expanded.
精彩评论