Unpossible
Unpossible

Reputation: 623

bash - store multiple items from a file line into array and store each item in its own variable

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

Answers (3)

user1934428
user1934428

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

Ivan
Ivan

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

tripleee
tripleee

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

Related Questions