I'm trying to do the following:
I have this file called testing.txt that I want to update each time the ip address or addresses change based on the name (test1ip, test2ip):
127.0.0.1 localhost
somotherrandomip testing
192.168.0.36 test1ip
192.168.0.37 test2ip
This is what I've tried.
#!/bin/bash
array=(
"192.168.0.34 test1ip"
"192.168.0.35 test2ip"
)
for i in "${array[@]}"; do
if ! grep -Fxq "$i" testing.txt
then
echo "ip-name=$i is not present, so adding it in testing.txt file"
echo "$i" >> testing.txt
else
echo "ip-name=$i is present in file, so nothing to do"
fi
done
However, this script appends a completely new line if the line is not found. What I would like to achieve is to overwrite the line if test1ip or test2ip is found but the ip address change.
Expected result:
127.0.0.1 localhost
somotherrandomip testing
192.168.0.34 test1ip
192.168.0.35 test2ip
I've also read this How to check if a string contains a substring in Bash but it seems i can't figure it out.
Any help is greatly appreciated!
CodePudding user response:
The following works on my machine. I changed the array to an associative array, removed the -x option to grep, and used sed
to edit the file in place.
#!/bin/bash
#associative array
declare -A array=(
[test1ip]="192.168.0.34"
[test2ip]="192.168.0.35"
)
#Loop over keys of the array
#See parameter expansion in bash manpage
for i in "${!array[@]}"; do
if ! grep -Fq "$i" testing.txt
then
echo "ip-name=$i is not present, so adding it in testing.txt file"
echo "${array[$i]} $i" >> testing.txt
else
echo "ip-name=$i is present in file so running sed"
#Replace old IP vith new IP
sed -Ei "s/[0-9] (\.[0-9] ){3} $i/${array[$i]} $i/" testing.txt
fi
done
CodePudding user response:
Here's a bash
awk
solution that'll do the job efficiently:
#!/bin/bash
array=(
"192.168.0.34 test1ip"
"192.168.0.35 test2ip"
"192.168.0.33 test3ip"
)
awk '
FNR == NR {
aarr[$2] = $1
next
}
! ($2 in aarr)
END {
for (host in aarr)
print aarr[host], host
}
' <(printf '%s\n' "${array[@]}") testing.txt
127.0.0.1 localhost
somotherrandomip testing
192.168.0.33 test3ip
192.168.0.34 test1ip
192.168.0.35 test2ip
notes:
bash
's<( commands )
is called process-subtitution. It creates a file containing the output ofcommands
that you can use as argument.awk
'sFNR == NR
is a condition for selecting the first file argument. In this block I create an associative array that translates a hostname to its new IP address.! ($2 in aarr)
means to print the records for which the hostname is not in the translation array.The
END
is for printing the translation array (new IPs of hostnames).