开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜