RambertNala
RambertNala

Reputation: 11

Shell Bash Script

I am making a bash script. I have to get 3 variables

VAR1=$(cat /path to my file/ | grep "string1" | awk '{ print $2 }'
VAR2=$(cat /path to my file/ | grep "string2" | awk '{ print $2 }'
VAR3=$(cat /path to my file/ | grep "string3" | awk '{ print $4 }'

My problem is that if I write

echo $VAR1
echo $VAR2
echo $VAR3

I can see values correctly

But when I try to write them in one line like this

echo "VAR1: $VAR1 VAR2: $VAR2 VAR3: $VAR3"

Value from $VAR3 is written at the beginning of output overwritting values of $VAR1 and $VAR2

I expect my explanation had been clear. Any doubt please let me know

Thanks and regards.

Rambert

Upvotes: 1

Views: 61

Answers (2)

sjsam
sjsam

Reputation: 21955

You could write :

cat /path to my file/ | grep "string1" | awk '{ print $2 }'

as

awk '/string1/{print $2}' /path/to/file

In other words you could do with awk alone what you intended to do with cat, grep & awk

So finally get :

VAR1=$(awk '/string1/{print $2}' /path/to/file) #mind the closing ')'

Regarding the issue you face, it looks like you have carriage returns or \r in your variables. In bash echo will not interpret escape sequences without the -e option, but the printf option which
[ @andlrc ] pointed out is a good try though as he mentioned in his [ answer ]

which in some shells will move the cursor to the beginning

Notes :

  1. Another subtle point to keep in mind is to avoid using upper case variable names like VAR1 for user scripts. So replace it with var1 or so
  2. When assigning values to variable spaces are not allowed around =, so

    VAR1="Note there are no spaces around = sign"
    

    is the right usage

Upvotes: 1

Andreas Louv
Andreas Louv

Reputation: 47099

It seems to me that $VAR3 contains \r which in some shells will move the cursor to the beginning of the line. Use printf instead:

printf "VAR1: %s VAR2: %s VAR3: %s\n" "$VAR1" "$VAR2" "$VAR3"

Also note that the way you extract the values is highly inefficient and can be reduced to one call to awk:

read -r var1 var2 var3 _ < <(awk '/string1/ { a=$2 }
                                  /string2/ { b=$2 }
                                  /string3/ { c=$4 }
                                        END { print(a, b, c) }' /path/to/file)
printf "VAR1: %s VAR2: %s VAR3: %s\n" "$var1" "$var2" "$var3"

A nitpick is that uppercase variable names are reserved for environment variables, so I changed all to lowercase.

<(...) is a process substitution and will make ... write to a "file" and return the file name:

$ echo <(ls)
/dev/fd/63

And command < file is a redirection changing standard input of command to be comming from the file file.

Upvotes: 5

Related Questions