Bash – Fix Case Statement Using Awk Commands in For Loop

awkbashcase

I have the following bash script:

#!/bin/bash

OUTPUT=NULL,2,3,NULL,5,6,7,8

pvar1=$(echo $OUTPUT | awk -F ',' '{print $1}')
pvar2=$(echo $OUTPUT | awk -F ',' '{print $2}')
pvar3=$(echo $OUTPUT | awk -F ',' '{print $3}')
pvar4=$(echo $OUTPUT | awk -F ',' '{print $4}')
pvar5=$(echo $OUTPUT | awk -F ',' '{print $5}')
pvar6=$(echo $OUTPUT | awk -F ',' '{print $6}')
pvar7=$(echo $OUTPUT | awk -F ',' '{print $7}')
pvar8=$(echo $OUTPUT | awk -F ',' '{print $8}')

for i in {$pvar1..$pvar8}
do

case "$i" in

        "NULL")
                pOUT="$(awk '{ $* = $* }1' FS=, OFS=, <<<"$OUTPUT")"
                ;;
        "")
                echo "particulars field is not allowed to be empty. Run the program again and enter NULL or choose a value!" && exit 0
                ;;
        *)
                pOUT="$(awk '{ $* = q $* q }1' FS=, OFS=, q="'"  <<<"$OUTPUT")"
                ;;

esac

done

echo "$pOUT"

The output should be:

pOUT=NULL,'2','3',NULL,'5','6','7','8'

And the script should exit if no value is provided, e.g.:

OUTPUT=NULL,2,3,NULL,5,6,,8

I am not sure how to write the awk commands in a for loop. Can someone please help?

Best Answer

Running awk to split one(!) field or join characters is wasteful and unnecessary; shell can do this fine. It's not clear exactly what you want because some of your code makes no sense at all, but based on your single example this should be close:

#!/bin/bash
OUTPUT=NULL,2,3,NULL,5,6,7,8

IFS=,; set -f; set -- $OUTPUT; out=
for i in "$@"; do case "$i" in # you _can_ omit in "$@" as the default, but this is clearer
"") echo empty input not allowed; exit 0;; # may want nonzero status for error
NULL) out="$out,$i";; *) out="$out,'$i'";; 
esac; done
echo "${out:1}" # bash only; or "${out#,}" on any Bourne/POSIX shell

# this leaves IFS and noglob set; for a standalone script this doesn't matter,
# but if source'd or entered manually you probably need to either reset these 
# explicitly or (more easily) put the whole thing in parentheses (a subshell)

but if you do want to use awk it can easily do the whole job at once

echo NULL,2,3,NULL,5,6,7,8 |\
awk -F, -vq=\' '{for(i=1;i<=NF;i++)if($i==""){print "empty not allowed";exit 0}
  else if($i=="NULL")out=out","$i; else out=out","q$(i)q; print substr(out,2)}'
# linebreak in script for clarity, may be omitted
# since there's only one line=record input, you _could_ 
# replace the for(...) with while(++i<=NF) but I don't like it

or even easier, perl:

echo NULL,2,3,NULL,5,6,7,8 |\
perl -lne 'print join ",",map{ length or die "empty not allowed"; $_=="NULL"?$_:"\047".$_."\047"}split(",")'
Related Question