Jordi
Jordi

Reputation: 23277

Shell script: strange behavior with awk

That's an shell script snippet:

KVS_VARIABLES=$(awk -F= '!($1 && $2 && NF==2) { print "File failed validation on line " NR | "cat 1>&2"; next } { print $1, $2 }' $ENV_FILE_LOCATION)
echo ${KVS_VARIABLES}

for kv in ${KVS_VARIABLES}
do
  echo $kv
  key=$(echo $kv | awk -FS=" " '{print $1}')
  value=$(echo $kv | awk -FS=" " '{print $2}')

  echo "key: $key | value: $value"
done

I expect an output like:

key: VAR1 | value: VAL1
...

However, I'm getting that:

VAR1 VAL1 VAR2 VAL2 VAR3 VAL3
VAR1
key: VAR1 | value: 
VAL1
key: VAL1 | value: 
VAR2
key: VAR2 | value: 
VAL2
key: VAL2 | value: 
VAR3
key: VAR3 | value: 
VAL3
key: VAL3 | value:

EDIT

File content is:

VAR1=VAL1
VAR2=VAL2
VAR3=VAL3

Upvotes: 0

Views: 52

Answers (2)

KamilCuk
KamilCuk

Reputation: 142005

It has nothing to do with awk.

KVS_VARIABLES="VAR1 VAL1
VAR2 VAL2
VAR3 VAL3"

Now with a for kv in ${KVS_VARIABLES} you just iterate over the words (single words, not lines). The newlines gets ignored, because the variable is not escaped.
Now you want to iterate over lines or read two variables at a time and print them in a fancy fashion.

You can read lines (probably this is what you want):

while read -r key value; do
   echo "key: $key | value: $value"
done <<<"$KVS_VARIABLES"

If you don't have bash>4 with here strings, you can try process substitution:

while read -r key value; do
   echo "key: $key | value: $value"
done < <(echo "$KVS_VARIABLES")

or a good old' pipe:

echo "$KVS_VARIABLES" | while read -r key value; do
   echo "key: $key | value: $value"
done

You can do iterate over two arguments at a time:

first=""
for kv in ${KVS_VARIABLES}; do
        if [ -z "$first" ]; then
                first="$kv"
        else
                echo "key: $first | value $kv"
                first=""
        fi
done

For a test, do in your console for kv in ${KVS_VARIABLES}; do echo kv=$kv; done and observe the output.

Upvotes: 0

oliv
oliv

Reputation: 13259

Try this awk script:

$ awk -F= -v OFS=' | ' '{$1="key: "$1;$2="value: "$2}1' file
key: VAR1 | value: VAL1
key: VAR2 | value: VAL2
key: VAR3 | value: VAL3

The input and output field separators are set to = and |values. The only awk statement is adding the string before keys and values.

Upvotes: 1

Related Questions