Reputation: 143
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.
Upvotes: 0
Views: 55
Reputation: 34324
Pushing the while
loop solution into a single awk
call:
awk -F";" ' # input delimiter is ";"
{ tag="UNDEFINED" } # default tag in case $1 does not match the following patterns
$1 ~ /jua/ { tag="jua" }
$1 ~ /tmb/ { tag="tmb" }
{ printf "<node name=\"%s\" tags=\"infra,%s,vm\" hostname=\"%s\" username=\"test\"/>\n", $1, tag, $2 }
' host.csv
This generates:
<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"/>
NOTES:
printf
to the final output file (alternatively, direct the entire output of the awk
call to said output file)username="test"
Upvotes: 1
Reputation: 34324
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:
printf
to the final destinationsed -i
callsusername="{test|tests}"
(though OP's sample output only shows the string test
); OP can edit the proposed code as neededUpvotes: 1
Reputation: 10123
A single GNU sed
call could do the job:
sed -E 's/([^-]*)-([^-]*)-([^;]*);(.*)/<node name="\1-\2-\3" tags="infra,\2,\1" hostname="\4" username="test"\/>/' file
Upvotes: 1