Reputation: 623
I have a file with multiple lines in this format (reverse dns entries):
251.2.168.192.in-addr.arpa core.admin.my.lan.
I'm trying to break up the line into multiple variables so I can use them to recreate its IP address, and use as an IPA DNS entry line
(
ipa dnsrecord-add admin.my.lan core --a-rec 192.168.2.251
).
So far I have been able to come up with this:
while read line ; do
IFS=', ' read -r -a my_array <<< $(echo $line | awk -F '[. ]' '{print $4, $3, $2, $1, $7, $8}')
while IFS= read -r first second third fourth fifth sixth; do
echo "first=$first second=$second third=$third fourth=$fourth fifth=$fifth sixth=$sixth";
done <<< "$my_array"
unset my_array
done <reverse_entries.txt
but this only creates the first variable $first
:
first=192 second= third= fourth= fifth= sixth=
first=10 second= third= fourth= fifth= sixth=
first=192 second= third= fourth= fifth= sixth=
first=192 second= third= fourth= fifth= sixth=
first=192 second= third= fourth= fifth= sixth=
first=192 second= third= fourth= fifth= sixth=
first=192 second= third= fourth= fifth= sixth=
Please what am I doing incorrectly?
Upvotes: 0
Views: 356
Reputation: 22356
The bug is
done <<< "$my_array"
which indeed will deliver the first element only. You want to transmit the whole array, and hence should write
done <<< "${my_array[@]}"
Of course I wonder why you need a dummy while-loop (the inner while will be executed only once for each iteration of the outer one), when you could do a simple
read -r first second third fourth fifth sixth <<< "${my_array[@]}"
and even makes sense only, if you really want to have the variables first
,... etc. as own non-array variables, because since you have the data already in the array, you could access them directly, for instance by ${my_array[0]}
for the first element.
Upvotes: 2
Reputation: 7317
Why you set IFS=', '
i don't see any commas in example. And using an array?
According to your example there are 2 main parts, first 251.2.168.192.in-addr.arpa
and second core.admin.my.lan.
So i would start from this, split lines in this two parts and than make them look like i need.
For this test file
$ cat reverse_entries.txt
251.2.168.192.in-addr.arpa core.admin.my.lan.
251.2.168.193.in-addr.arpa coe.admin.my.lan.
251.2.168.194.in-addr.arpa cor.admin.my.lan.
while read line ; do
read -r ip name <<< $line
ip=${ip/.in-addr.arpa/} # remove .in-addr.arpa from ip
ip=( ${ip//./ } ) # make ip an array
ip=${ip[3]}.${ip[2]}.${ip[1]}.${ip[0]} # reconstruct ip
core=${name%%.*} # get core part from name
name=${name%.} # remove last dot from name
name=${name#*.} # remove core. from name
# print result line
echo "ipa dnsrecord-add $name $core --a-rec $ip"
done < reverse_entries.txt
The output
ipa dnsrecord-add admin.my.lan core --a-rec 251.2.168.192
ipa dnsrecord-add admin.my.lan coe --a-rec 251.2.168.193
ipa dnsrecord-add admin.my.lan cor --a-rec 251.2.168.194
Upvotes: 2
Reputation: 189908
Your script looks like you should rewrite all of it in Awk; but here is a simple Bash script which hopefully offers at least a hint as to how your script could be simplified if you really want to write it in Bash.
#!/bin/bash
split () {
local IFS='.'
printf ' %s' $*
}
while read ptr fqdn; do
ips=($(split "$ptr"))
domain=${fqdn#*.}
host=${fqdn%.$domain}
echo "ipa dnsrecord-add ${domain%.} $host --a-rec ${ips[3]}.${ips[2]}.${ips[1]}.${ips[0]}"
done <<\:
251.2.168.192.in-addr.arpa core.admin.my.lan.
:
Output:
ipa dnsrecord-add admin.my.lan core --a-rec 192.168.2.251
Here's a quick and dirty Awk reimplementation.
awk '{ split($1, rev, /[.]/); split($2, fqdn, /[.]/);
domain=$2; sub("^" fqdn[1] "[.]", "", domain); sub(/[.]$/, "", domain);
print "ipa dnsrecord-add", fqdn[1], domain,\
"--a-rec", rev[4] "." rev[3] "." rev[2] "." rev[1] }' reverse_entries.txt
Upvotes: 1