0

我有一个具有这种格式的多行文件(反向 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=

请问我做错了什么?

4

3 回答 3

2

为什么你设置IFS=', '我在示例中看不到任何逗号。并使用数组?根据您的示例,有两个主要部分,第一个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
于 2020-02-03T07:02:19.503 回答
2

错误是

done <<< "$my_array"

这确实只会提供第一个元素。你想传输整个数组,因此应该写

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

当然我想知道为什么你需要一个虚拟的 while 循环(内部while将只执行一次外部循环的每次迭代),当你可以做一个简单的

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

first甚至只有在你真的想将变量等作为自己的非数组变量时才有意义,因为由于数组中已经有数据,你可以直接访问它们,例如${my_array[0]}第一个元素。

于 2020-02-03T10:33:39.080 回答
1

您的脚本看起来应该在 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
于 2020-02-03T06:57:54.960 回答