Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you use heredocuments to embed AWK in a bash script?

Tags:

bash

awk

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 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?

like image 464
mike3996 Avatar asked Jun 27 '11 07:06

mike3996


People also ask

Can I use awk in bash?

AWK is a programming language that is designed for processing text-based data, either in files or data streams, or using shell pipes. In other words you can combine awk with shell scripts or directly use at a shell prompt. This pages shows how to use awk in your bash shell scripts.

How do I run an awk script in bash?

awk Scripts Tell the shell which executable to use to run the script. Prepare awk to use the FS field separator variable to read input text with fields separated by colons ( : ). Use the OFS output field separator to tell awk to use colons ( : ) to separate fields in the output. Set a counter to 0 (zero).

How do you call an awk script?

In order to tell awk to use that file for its program, you type: awk -f source-file input-file1 input-file2 … The -f instructs the awk utility to get the awk program from the file source-file (see Command-Line Options). Any filename can be used for source-file .

What is awk in shell script?

The awk command is a Linux tool and programming language that allows users to process and manipulate data and produce formatted reports. The tool supports various operations for advanced text processing and facilitates expressing complex data selections.


2 Answers

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}
like image 106
mss Avatar answered Oct 14 '22 06:10

mss


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
like image 36
David Given Avatar answered Oct 14 '22 05:10

David Given