LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   For loop with embedded "growing" variable (https://www.linuxquestions.org/questions/linux-newbie-8/for-loop-with-embedded-growing-variable-4175643166/)

flukeyLinux 11-27-2018 04:10 AM

For loop with embedded "growing" variable
 
Hi all,

I've been trying to grep for a value in numerous files with a for loop. What I want is for the result of each loop to be saved as a variable +1 like below:

A=$(0)
for i in `cat zone_files.txt`
do
echo ***$i***
databaseip[$A]="$(grep postgres_host settings/$i | awk '{print $2}')"
let "A++"
done

For some reason the IP addresses I am trying to save are not saving to variables:
$databaseip0
$databaseip1
$databaseip2
$databaseip3

Can anyone see what I am missing?

The Numberic value seems to work ok. if I add "echo $databaseip$A" I get 3 which is the correct number of the variable but it is missing the IP.

My zones_files.txt file just shows a list of 3 zones. the for loop looks for configuration files in those zones under "/settings/" and just greps for the database IP. Manually this works. But for some reason I can't get the IP's assigned to the variables numerically.

thanks in advance.
flukeyLinux

l0f4r0 11-27-2018 05:05 AM

I think there are some mistakes.

Code:

databaseip[$A]
seems to indicate that databaseip is an array.

VS.

Code:

For some reason the IP addresses I am trying to save are not saving to variables:
$databaseip0
$databaseip1
$databaseip2
$databaseip3

seems to indicate that databaseip0, databaseip1, databaseip2... are separate variables...

=>So you need to choose what strategy you prefer.
If you want databaseip to be an array, you don't need to change anything but you will enumerate its data with:
Code:

echo "${databaseip[@]}"
So it's normal if databaseip0, databaseip1, databaseip2, databaseip3 don't exist, hence don't contain your data ;)

Btw, replace
Code:

A=$(0)
with
Code:

A=0

flukeyLinux 11-27-2018 05:59 AM

Quote:

Originally Posted by l0f4r0 (Post 5930547)
I think there are some mistakes.

Code:

databaseip[$A]
seems to indicate that databaseip is an array.

VS.

Code:

For some reason the IP addresses I am trying to save are not saving to variables:
$databaseip0
$databaseip1
$databaseip2
$databaseip3

seems to indicate that databaseip0, databaseip1, databaseip2... are separate variables...

=>So you need to choose what strategy you prefer.
If you want databaseip to be an array, you don't need to change anything but you will enumerate its data with:
Code:

echo "${databaseip[@]}"
So it's normal if databaseip0, databaseip1, databaseip2, databaseip3 don't exist, hence don't contain your data ;)

Btw, replace
Code:

A=$(0)
with
Code:

A=0


This works now thank you, I can see the values. I was using A=0 but in my messing about, was trying a few different options.

echo "${databaseip[@]}" is displaying what I need to see. What I would like to do is assign each IP to a variable like databaseip0 (for zone 0), databaseip1 (for zone 1) etc...
So that I can then populate another file with those IP's basically.

databaseip[@] shows me the list of IP's and appends them like this:
***qa-iaas-z1.yml***
echo "${databaseip[@]}" = IP0 IP1 IP2 IP3

Appreciate the help on this!

grail 11-27-2018 06:29 AM

It would seem you are not used to working with arrays. In bash you would recall each item at the position want, like so:
Code:

${databaseip[@]} -- all items in array (use double quotes if whitespace is to be preserved)

${databaseip[0]} -- refers to first items in array
${databaseip[1]} -- refers to second
 ...

As for your current code, it could be a deal simpler:
Code:

while read -r _ filename _
do
  databaseip+=($(awk '/postgres_host/{print $2}' "settings/$filename"))
done<zone_files.txt


l0f4r0 11-27-2018 06:32 AM

Maybe you are asking for separate variables databaseip0, databaseip1, databaseip2 because you are not aware that your databaseip array values can already be accessed independently.
If so, note that you can achieve what you need with what you already have ie databaseip.
Here are some ways you can access your data:
Code:

for elem in ${databaseip[@]}; do echo "$elem"; done;
Code:

for (( i=0; i<${#databaseip[@]}; i++ )); do echo "${databaseip[$i]}"; done;
Tell us if this is not what you want.

l0f4r0 11-27-2018 06:51 AM

Quote:

Originally Posted by grail (Post 5930572)
Code:

while read -r _ filename _

Can you explain this to me please?

EDIT: ok it seems you use a throwaway variable to ignore field 1 and field3+
Does your command work? My tests are not very successful but I don't know the files structure under /settings...

grail 11-27-2018 07:16 AM

Quote:

Originally Posted by l0f4r0 (Post 5930579)
Can you explain this to me please?

EDIT: ok it seems you use a throwaway variable to ignore field 1 and field3+
Does your command work? My tests are not very successful but I don't know the files structure under /settings...

I have not tested it, as I have no idea of file format, but assuming as you said that there are at least 2 fields, the logic should be sound

Let me know where you are having an error? (you can of course use set -xv to see what may be going wrong)

Mickie 11-27-2018 07:26 AM

Best web hosting provider
 
Got a best place to read nice post.

l0f4r0 11-27-2018 07:38 AM

Quote:

Originally Posted by Mickie (Post 5930587)
Title: Best web hosting provider
Got a best place to read nice post.

Off topic, even start of SPAM. Reported for deletion.

l0f4r0 11-27-2018 07:42 AM

Quote:

Originally Posted by grail (Post 5930583)
I have not tested it, as I have no idea of file format, but assuming as you said that there are at least 2 fields, the logic should be sound
Let me know where you are having an error? (you can of course use set -xv to see what may be going wrong)

I'm not the OP :D
I'm like you, I don't know how files under settings folder are decomposed... ;)

@flukeyLinux: only you can test the command and see if it meets your need.

flukeyLinux 11-27-2018 09:22 AM

Quote:

Originally Posted by l0f4r0 (Post 5930598)
I'm not the OP :D
I'm like you, I don't know how files under settings folder are decomposed... ;)

@flukeyLinux: only you can test the command and see if it meets your need.

Yep thanks guys.

Am testing and will let you know. the format of the files are simple text files with a single DB IP.

But if I get this working, I also need to retrieve web node IP address which look more like this:

nodes:
- IP
- IP
- IP

but I will deal with that when I get there :). Am considering using json to do this as well. But I will try this first as I know even less about jq.

thank you!

flukeyLinux 11-27-2018 11:37 AM

ok I ended up going with, creating a zones array and asking for a variable. so the script runs like ./script $environment. It then loops through each zone looking for the environment inputted and looks for the IP's I was referring to using jq.

Snippet:
web_ip[0]=$(yaml2json < settings/$env_name-$zone.yml | jq -r '."web-ips"| .[0]')
web_ip[1]=$(yaml2json < settings/$env_name-$zone.yml | jq -r '."web-ips"| .[1]')
web_ip[2]=$(yaml2json < settings/$env_name-$zone.yml | jq -r '."web-ips"| .[2]')
influx_ip=$(yaml2json < settings/$env-name-$zone.yml | jq -r '."influxdb_ip"| .')
postgres_ip=$(yaml2json < settings/$env-name-$zone.yml | jq -r '."postgres_host"| .')

Then I used EOL to output the variables above into a json format (not great but does the job well. If I knew more about jq I would use that).

cat >>contents <<EOL
{
"name":"$zone",
"web_ips":["${web_ip[0]}","${web_ip[1]}","${web_ip[2]}"],
"influx_ip":"${influx_ip}",
"database_ip":"${postgres_ip}"
},
EOL


I needed to append that zone data to another file (getting away from zones) so used an if statement to see if similar data already existed, if it did, exit if not, append.

if grep -q "environment-settings" settings/$env_name-$zone.yml;
then
echo -e "Environment-settings already exist for $env_name. Nothing to do"
echo "Exiting..."
exit 0
else
echo "Appending contents to settings/$env_name.yml:"
cat contents >> settings/$env_name.yml
rm contents
fi


Thought I would reply in case someone else was having a similar issue. Thanks for your help!

grail 11-28-2018 12:10 AM

It probably would have helped if you had mentioned you were dealing with json / yaml files to start with.

I take it you went this way as none of the posted solutions worked for you

l0f4r0 11-28-2018 07:18 AM

Ok, glad everything's fine for you now, even if, as evoked by grail, your solution doesn't seem to be directly related to the original question asked...
Please use [CODE] tags and please mark your thread as [SOLVED].


All times are GMT -5. The time now is 05:07 PM.