Shell – Use awk interactively through a pipe

awkpipeshell

Looking at this question, I've noticed that awk can't read user
input if the file is being piped into standard input, but it does
behave as expected if reading input from a file given as a command
line parameter.

For instance, if you have the following BEGIN block in your awk script:

BEGIN {
    printf "Enter input: "
    getline var < "-"
}

If you run it like awk -f ./script.awk file.txt, it will ask prompt
for user input, and then will proceed processing file.txt. However,
if you run like cat file.txt | awk -f ./script.awk, I suppose awk
will interpret what it is getting from the pipe as the user's input
(so getline will fill var with the first line of file.txt).

Is there a way to make awk behave like it is reading from a file, but being used in a pipe?

I can use a temporary file, sure, but this is far from elegant.

Best Answer

Instead of a temporary file, you could use of your shell's support for process substitution (this assumes bash, zsh or some implementations of ksh (the feature was introduced by ksh88)):

awk -f ./script.awk <(cat file.txt)

This will provide awk a file name in place of the <(...) construct which, when read, will contain the output of the enclosed command.

Related Question