19

I've been using a bash script (script.sh) which uses various awk scripts (script1.awk,script2.awk) which are tailored at "runtime", by replacing values for instance. I've been looking for ways to embed them completely within the first bash script. Ideally, I would like to have a file looking like this :

################################
# AWK scripts                  #
################################
read -d '' scriptVariable <<'EOF'
'
{my block commands;}
'
EOF
################################
# End of AWK Scripts           #
################################
awk $scriptVariable ${inputfile} # This line obviously doesn't work

instead of the traditional :

awk '{
my script commands
' ${intputfile}

Of course, I could write them to a file but the whole point is not to. Any suggestions ?

EDIT : Although dogbane answers works fine, the next problem is that with the <<'HERE' tags, newline characters are not read.I can't unquote it since, otherwise, he's trying to interpret the awk script then encountering a $ sign within (and there are). And with no newlines, I can't comment anything within the awk script (without commenting half the script when the newlines characters are being removed ...). Anyone ?

<< 'EOF'
BEGIN{#Hello
print $1
}
EOF # Is read as BEGIN{#Hello print $1} by awk; ie BEGIN{

<< EOF
BEGIN{#Hello
print $1
}
EOF #Is read correctly by awk but Bash tried to express $1 and fails
7
  • Does it work with awk "$scriptVariable" ${inputfile} Commented Feb 22, 2013 at 8:44
  • It sounds like you simply need to upgrade your scripting language to something better - Perl or Python. It will be easier and work faster. Commented Feb 22, 2013 at 8:45
  • Already tried, it failed with awk: syntax error at source line 1 context is >>> ' <<< awk: bailing out at source line 18 Commented Feb 22, 2013 at 8:47
  • why are you reading the variable when you can just set it with scriptVar='...' or better yet skip the whole setting of a variable and just use awk ' ... ' file ? Commented Feb 22, 2013 at 9:05
  • @technosaurus 1.Because there are nasty characters (',",..) in my string 2.Because I want to segregate the bash code and the awk code. Commented Feb 22, 2013 at 9:18

3 Answers 3

19

Remove the single quotes around the awk script and enclose the script variable in double-quotes. This works for me:

################################
# AWK scripts                  #
################################
read -d '' scriptVariable << 'EOF'
BEGIN {
    print "start"
}
{
    print $0
}
END{
    print "hello"
}
EOF
################################
# End of AWK Scripts           #
################################

awk "$scriptVariable" ${inputfile}
Sign up to request clarification or add additional context in comments.

1 Comment

To pass shell vars to the Awk script, use Awk's "-v" option. Something like: var v1 = "shell value" awk -v awkVar="$v1" "$scriptVariable" ${inputfile} In your script, 'awkVar' will hold the value "shell value"
2

The single quotes around awk scripts can be cantankerous in a shell.

echo dummy code | awk '/dummy/{print '$1' $2}' - another_file | while read LINE; do
    case $LINE in
        "$1 code")echo success;;
        *)echo $LINE;;
    esac
done

This will remove from stdin and then another_file and output lines containing dummy and replace the first field with the first argument to your bash script. Notice that the bash variable $1 had to be unquoted.

Comments

1

You can include your awk inside your bash script using a Here-Document.

3 Comments

A tip on that, use the -f - option, as in awk -f - << EOD
Why is the second - required?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.