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
7
  • 1
    Use "${var}" instead of just $var; ${x}${y} instead of $x$y. See unix.stackexchange.com/questions/4899/… Commented Feb 8, 2019 at 6:57
  • 2
    I don't see any way that the braces would make a lick of difference there. Commented Feb 8, 2019 at 7:07
  • Kenneth, I tried your solution but result is the same. The output is: taskscript.sh: line 16: ${v1$i}: bad substitution
    – user335832
    Commented Feb 8, 2019 at 7:18
  • @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. Commented Feb 8, 2019 at 7:20
  • 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
    Commented Feb 8, 2019 at 8:52

3 Answers 3

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.

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.

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]}" )

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .