Issue
I want to create a .xml file with an specific config, this config needs an hostname and ip, i have created the hosts.csv
to input this data being them vm-tmb-test1;127.0.0.1
on .csv file
for each separator line ";"
is a hostname and ip of a server, but the looping i have created print for each ip in the hosts.csv
Code Structure
#!/bin/bash
for i in $(cat /var/projects/etc/hosts.csv | cut -d\; -f1)
do
for ips in $(cat /var/projects/etc/hosts.csv | cut -d\; -f2)
do
if [[ ${i} == *"jua"* ]]
then
sed -i '$ a <node name="'${i}'" tags="infra,jua,vm" hostname="'${ips}'" username="test"/>' /var/projects/etc/resources.xml
elif [[ ${i} == *"tmb"* ]]
then
sed -i '$ a <node name="'${i}'" tags="infra,tmb,vm" hostname="'${ips}'" username="tests"/>' /var/projects/etc/resources.xml
fi
done
done
Host.csv content:
vm-tmb-test1;127.0.0.1
vm-tmb-test2;127.0.0.2
vm-tmb-test3;127.0.0.3
vm-jua-test4;127.0.0.4
Desired Output:
<node name="vm-tmb-test1" tags="infra,tmb,vm" hostname="127.0.0.1" username="test"/>
<node name="vm-tmb-test2" tags="infra,tmb,vm" hostname="127.0.0.2" username="test"/>
<node name="vm-tmb-test3" tags="infra,tmb,vm" hostname="127.0.0.3" username="test"/>
<node name="vm-jua-test4" tags="infra,jua,vm" hostname="127.0.0.4" username="test"/>
Actual Code Output:
<node name="vm-tmb-test1" tags="infra,tmb,vm" hostname="127.0.0.1" username="test"/>
<node name="vm-tmb-test1" tags="infra,tmb,vm" hostname="127.0.0.2" username="test"/>
<node name="vm-tmb-test1" tags="infra,tmb,vm" hostname="127.0.0.3" username="test"/>
<node name="vm-tmb-test1" tags="infra,tmb,vm" hostname="127.0.0.4" username="test"/>
<node name="vm-tmb-test2" tags="infra,tmb,vm" hostname="127.0.0.1" username="test"/>
<node name="vm-tmb-test2" tags="infra,tmb,vm" hostname="127.0.0.2" username="test"/>
<node name="vm-tmb-test2" tags="infra,tmb,vm" hostname="127.0.0.3" username="test"/>
<node name="vm-tmb-test2" tags="infra,tmb,vm" hostname="127.0.0.4" username="test"/>
How can i fix that?
Edit 1: host.csv contains then more of 200 servers hostname and ip's it will be fed with time.
Solution
While faster solutions (eg, awk
, sed
) exist, for this answer I'm going to stick with OP's idea of using a loop ...
Sample input:
$ cat host.csv
vm-tmb-test1;127.0.0.1
vm-tmb-test2;127.0.0.2
vm-tmb-test3;127.0.0.3
vm-jua-test4;127.0.0.4
Since the sample code appears to just be appending output to a *.xml
file I'm going to opt for a single while
loop that generates the desired output:
while IFS=";" read -r i ips # use ';' as input delimiter and read values into our 2 variables 'i' and 'ips'
do
tag='UNDEFINED' # define some defaults in case 'i' does not
uname='UNDEFINED' # have a match in our case statement
case "${i}" in # pattern match 'i' to determine what strings to submit to the printf command
*jua*) tag='jua' ; uname='test' ;;
*tmb*) tag='tmb' ; uname='tests' ;;
esac
printf '<node name="%s" tags="infra,%s,vm" hostname="%s" username="%s"/>\n' "${i}" "${tag}" "${ips}" "${uname}"
done < host.csv
The above generates:
<node name="vm-tmb-test1" tags="infra,tmb,vm" hostname="127.0.0.1" username="tests"/>
<node name="vm-tmb-test2" tags="infra,tmb,vm" hostname="127.0.0.2" username="tests"/>
<node name="vm-tmb-test3" tags="infra,tmb,vm" hostname="127.0.0.3" username="tests"/>
<node name="vm-jua-test4" tags="infra,jua,vm" hostname="127.0.0.4" username="test"/>
NOTES:
- OP can redirect the output of the
printf
to the final destination - this should be a bit more efficient than repetitive
sed -i
calls - I have copied OPs code snippet that shows the use of
username="{test|tests}"
(though OP's sample output only shows the stringtest
); OP can edit the proposed code as needed
Answered By - markp-fuso