0

I have a bash script which contains awscli as well. I am trying to print a variable which is created in a for loop. The variable that I am trying to print contains $ sign because of for loop. I couldn't print the value. Below I am sharing the script. The output of this script is only numbers which is generated in the for loop. I want to print the value which is generated in the command.

#!/bin/bash

declare -i counter=11
declare -i counter2=14

for i in {1..2}
do
    declare v1$i=$(aws iam get-group --group-name VideoEditors | awk -v counter1=$counter 'NR==counter1' | awk -F\" '{print $4}') 

    counter=$counter+7

    declare v2$i=$(aws iam get-group --group-name VideoEditors | awk -v counter3=$counter2 'NR==counter3' | awk -F\" '{print $4}')

    counter2=$counter2+7
    echo $v1$i
    echo $v2$i
done
ilkkachu
  • 138,973
  • 1
    Use "${var}" instead of just $var; ${x}${y} instead of $x$y. See https://unix.stackexchange.com/questions/4899/var-vs-var-and-to-quote-or-not-to-quote – Kenneth B. Jensen Feb 08 '19 at 06:57
  • 2
    I don't see any way that the braces would make a lick of difference there. – Michael Homer Feb 08 '19 at 07:07
  • @MichaelHomer I've performed several more tests; turns out that I was printing just $y, which was identical to $x$y. OP, my advice would be to use an array for v1 and v2 instead of v11/v12/v21/v22/etc. – Kenneth B. Jensen Feb 08 '19 at 07:20
  • Kenneth, I tried your solution but result is the same. The output is: taskscript.sh: line 16: ${v1$i}: bad substitution – user335832 Feb 08 '19 at 07:18
  • If you're only outputting the result of the awk calls, why are you even trying to store it in variables? – Kusalananda Feb 08 '19 at 08:06
  • Also, use counter=$(( counter + 7 )) to increment your counter. – Kusalananda Feb 08 '19 at 08:46
  • 1
    @Kusalananda, the addition works since they're declared integer variables. Even counter+=7 would do. Though I'm not sure if it would be more readable to just use $(( .. )) with regular variables ... – ilkkachu Feb 08 '19 at 08:52

3 Answers3

0

Use an array instead, that allows you to properly index the variables:

#!/bin/bash

declare -ai counters=(11 14)        # indexes start from 0
v1=()
v2=()    

for i in {1..2}; do
    v1[$i]=$(aws iam get-group --group-name VideoEditors | awk -v counter1="$counter" 'NR==counter1' | awk -F\" '{print $4}') 
    counters[0]+=7

    v2[$i]=$(aws iam get-group --group-name VideoEditors | awk -v counter3="$counter2" 'NR==counter3' | awk -F\" '{print $4}')
    counters[1]+=7

    echo "${v1[$i]}"
    echo "${v2[$i]}"
done

You could probably put the vN assignments within another for loop to reduce the repetition.

Of course, if you're not using v1 and v2 for anything other than displaying the values once, you could just run aws ... | awk directly and skip the variables and the echo.

ilkkachu
  • 138,973
0

I don't know what your code is supposed to accomplish but what it does is this:

In the first iteration - when i equals 1 - it declares variables v11 and v12 and assigns something to them and then prints $v1$i to the screen.

v1 is non-existent and $i is the value of i, so you should get 'nothing' with an appended 1 as output in the first loop:

And then in the second iteration - when i equals 2 - two times 2 for the same reason.

What you do after the equal sign with awk etc. is irrelevant for the outcome.

The suggestion to use an array and use $i as an index into it will solve the problem.

Arjen
  • 188
0

You seem to want to output the fourth "-delimited field on lines 11, 17, 18, and 21 of the output of an aws command.

aws iam get-group --group-name VideoEditors |
awk -F '"' 'NR == 11 || NR == 17 || NR == 18 || NR == 21 { print $4 }'

This calls aws once instead of four times, and calls awk once instead of eight times.

If you want this in an array:

readarray -t output < <(
aws iam get-group --group-name VideoEditors |
awk -F '"' 'NR == 11 || NR == 17 || NR == 18 || NR == 21 { print $4 }' )

The array output would now contain the data with one line from awk in each element, starting at index 0.

If you want to split that array into two, so that you get element 0 and 2 in one and 1 and 3 in the other:

v1=( "${output[0]}" "${output[2]}" )
v2=( "${output[1]}" "${output[3]}" )
Kusalananda
  • 333,661