bash - сохранить несколько элементов из строки файла в массив и сохранить каждый элемент в своей переменной - PullRequest
0 голосов
/ 03 февраля 2020

У меня есть файл с несколькими строками в этом формате (обратные записи DNS):

251.2.168.192.in-addr.arpa core.admin.my.lan.

Я пытаюсь разбить строку на несколько переменных, чтобы я мог использовать они воссоздают его IP-адрес и используют в качестве строки ввода IPA DNS

(ipa dnsrecord-add admin.my.lan core --a-rec 192.168.2.251).

До сих пор мне удавалось придумать это:

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

но при этом создается только первая переменная $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=

Пожалуйста, что я делаю неправильно?

Ответы [ 3 ]

2 голосов
/ 03 февраля 2020

Почему вы устанавливаете IFS=', ' Я не вижу запятых в примере. И используя массив? В соответствии с вашим примером есть 2 основные части, первая 251.2.168.192.in-addr.arpa и вторая core.admin.my.lan. Так что я бы начал с этого, разделив строки на эти две части и затем заставив их выглядеть так, как мне нужно.

Для этого теста файл

$ 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

Выход

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
2 голосов
/ 03 февраля 2020

Ошибка

done <<< "$my_array"

, которая действительно доставит только первый элемент. Вы хотите передать весь массив, и, следовательно, должны написать

done <<< "${my_array[@]}"

Конечно, мне интересно, почему вам нужен манекен while-l oop (внутренний while будет выполняться только один раз для каждой итерации внешней), когда вы могли бы сделать простой

read -r first second third fourth fifth sixth <<< "${my_array[@]}"

и даже имеет смысл только, если вы действительно хотите иметь переменные first ,. .. et c. как собственные переменные, не являющиеся массивами, поскольку, поскольку у вас есть данные, уже находящиеся в массиве, вы можете обращаться к ним напрямую, например, с помощью ${my_array[0]} для первого элемента.

1 голос
/ 03 февраля 2020

Ваш скрипт выглядит так, как будто вы должны переписать все это в Awk; но вот простой Bash скрипт, который, как мы надеемся, предлагает хотя бы подсказку о том, как можно упростить ваш скрипт, если вы действительно хотите написать его в 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.
:

Вывод:

ipa dnsrecord-add admin.my.lan core --a-rec 192.168.2.251

Вот быстрое и грязное переопределение Awk.

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
...