awk '/^#/ {next}; NF == 0 {next}; NF != 4 {exit 1} ; {print}' |
while read -r NAME METHOD URL TAG ; do
: # do stuff with $NAME, $METHOD, $URL, $TAG
echo "$NAME:$METHOD:$URL:$TAG"
done
if [ "$PIPESTATUS" -eq 1 ] ; then
: # do something to handle awk's exit code
fi
$ cat input.txt
# comment
NAME METHOD URL TAG
a b c d
1 2 3 4
x y z
a b c d
$ ./testawk.sh <inputinput.txt
NAME:METHOD:URL:TAG
a:b:c:d
1:2:3:4
Note that it correctly exits on the fifth x y z input line.
It's worth pointing out that because the while loop is the target of a pipe, it executes in a sub-shell and is therefore unable to alter the environment (including environment variables) of its parent script.
If that is required, then don't use a pipe, use redirection and process substitution instead:
while read -r NAME METHOD URL TAG ; do
: # do stuff with $NAME, $METHOD, $URL, $TAG
echo "$NAME:$METHOD:$URL:$TAG"
done < <(awk '(/^#/ || NF == 0) {next};
NF != 4 {
printf "Error on %s:%s\n", FILENAME, NR > "/dev/stderr";
exit 1
};
{print}' input.txt)
# getting the exit code from the <(...) requires bash 4.4 or newer:
wait $!
if [ "$?" -ne 0 ] ; then
: # something went wrong in the process substitution, deal with it
fi
Alternatively, you can use the coproc built-in to run the awk script in the background as a co-process:
# By default, array var $COPROC holds the co-process' stdout and
# stdin file descriptors. See `help coproc`.
coproc {
awk '(/^#/ || NF == 0) {next};
NF != 4 {
printf "Error on %s:%s\n", FILENAME, NR > "/dev/stderr";
exit 1
};
{print}' input.txt
}
awkpid="$!"
#declare -p COPROC # uncomment to see the FDs
while read -r NAME METHOD URL TAG ; do
echo "$NAME:$METHOD:$URL:$TAG"
done <&"${COPROC[0]}"
wait "$awkpid"
echo "$?"