Reputation: 29
I am trying to write a script that generates csv files from mysql. The csv files from mysql is working fine, however, I'm struggling with a way to loop through variables, or treat them as an array to loop through.
Some example variables are below
c1="Client 1"
c1_s1_name=Alpha
c1_s1_id=761967
c1_s2_name=Beta
c1_s2_id=415612
c2="Client 2"
c2_s1_name=XYZ
c2_s1_id=438976
c2_s2_name=ABC
c2_s2_id=982012
c3="Client 3"
c3_s1_name=No-Name
c3_s1_id=347654
c3_s2_name=House
c3_s2_id=109321
I then have some quasi-code that attempts to run a sql script for each client
as below but
# loop through all clients
for all_clients in $c1 $c2 $c3
do
# and then loop through for all survey names and all survey ids for each seperate client
for survey_name in $*_name and survey_id in $*_id
do
mysql -h "localhost" -u "root" "$DATABASE" -e "SELECT count(*) FROM $survey_id" | sed 's/\t/","/g;s/^/"/;s/$/"/;s/\n//g' > $all_clients-$survey_name-filename-count.csv
done
done
I'm not sure how to set the script up so that the c1
variables are run as a set and then c2
, followed by c3
. I'm guessing an array might be what I need but I'm not sure?
I've also come across the answer below but it's for PHP, even though it looks suspiciously like bash...
Group variables and loop through them
Upvotes: 1
Views: 54
Reputation: 2544
You need to build the name of your dynamic variable and then dereference it with the {!var}
syntax. Granted that you know your variable names in advance (i.e. the first part is always c1
, c2
or c3
, the second part is always s1
or s2
, …), you can use something like that:
for x in c1 c2 c3; do
for y in s1 s2; do
for z in name id; do
xyz=${x}_${y}_${z}
# Use ${!xyz} to get the contents of the variable
done
done
done
Example (but without your mysql call, obviously)
I have used x
, y
and z
to emphasize how the variable is constructed, but
you can replace x
by all_clients
, etc..
You can use a slightly more advanced technique if the number of c*
and s*
is not known in advance.
numc=3
nums=2
for x in $(seq -f 'c%g' $numc); do
for y in $(seq -f 's%g' $nums); do
for z in name id; do
xyz=${x}_${y}_${z}
# Use ${!xyz} to get the contents of the variable
done
done
done
The magic here is from seq
. For example, in the following call:
seq -f 'c%g' $numc
The $numc
option says you want to iterate from 1
to $numc
. The -f 'c%g'
option says that you want to form a printf
-like string, in this case the letter c
followed by the numeric value. So, the above example will write:
c1
c2
c3
The whole string is captured by $()
which means the output will be inlined in your script. All in all, the following line:
for x in $(seq -f 'c%g' $numc); do
Will be interpreted as:
for x in c1 c2 c3; do
Which is equivalent to the initial for
loop, except that now you control the number of iterations.
Upvotes: 1