How to convert forward zone file to reverse

I have forward dns zone file with A records and converting it to reverse zone file
ex.

subdomain1 A 10.20.30.40
subdomain2 A 10.20.31.41
subdomain3 A 10.20.35.43
subdomain4 A 10.20.30.41
subdomain5 A 10.20.30.42

Need to convert reverse like:

10.20.30.40
40 PTR subdomain1.domain.com
41 PTR subdomain4.domain.com
42 PTR subdomain5.domain.com
10.20.31.41
41 PTR subdomain2.domain.com
10.20.35.43
43 PTR subdomain3.domain.com

I am doing this with below command but not satisfied, I know there is better way to do this but need right direction.

for line in $(cat zonefile );
do
        name = $(echo $line | cut -d' ' -f1)
        IP = $(echo $line | cut -d. -f4)
        echo -e "$IP \t PTR \t $name.domanin.com"
done

I doubt that you are doing it with the script you posted; there are errors in that script. When posting code, use the exact code. Cut and paste it, do not retype it.

That is almost always the wrong way to read a file.

You are not reading it a line at a time, but a word at a time.

Use a while loop:

while IFS= read -r line
do
  : ...
done < zonefile

There must be no spaces around the equals signs.

You do not need an external command to split a line. Use the shell's parameter expansion or IFS and set:

name=${line%% *}
set -f; IFS=.; set -- $line
shift $(( $# - 1 ))
IP=$4

There's usually not much reason to use cut when the read builtin can handle delimiters more elegantly. Here it takes two delimiters, period and space, to split the string into words and individual numbers at the same time. It also checks when the first three change and prints out the address entire, as your output data suggests you want.

IFS=" ."
while read NAME G A B C D && [[ ! -z "$NAME" ]]
do
        if      [[ "$A" != "$AA" ]]     ||
                [[ "$B" != "$BB" ]]     ||
                [[ "$C" != "$CC" ]]
        then
                echo "$A.$B.$C.$D"
        fi

        AA="$A" ; BB="$B" ; CC="$C" ; DD="$D"

        echo -e "$D\tPTR\t$NAME.domain.com"
done < zonefile

I was looking for right direction and you gave it me... thank you!

you got it right! thank you!

The output data doesn't look right to me because the
lines:

10.20.30.40
40 PTR subdomain1.domain.com
41 PTR subdomain4.domain.com
42 PTR subdomain5.domain.com

don't look like they imply that the last 40 is substituted by the first field in subsequent lines.

At any rate -- here's my ksh solution (late)

 
prev_key=some-junk
 
cat << EOF |
subdomain1 A 10.20.30.40
subdomain2 A 10.20.31.41
subdomain3 A 10.20.35.43
subdomain4 A 10.20.30.41
subdomain5 A 10.20.30.42
EOF
#----------------------------------------------------------------------#
# Convert spaces to dots.                                              #
#----------------------------------------------------------------------#
sed -e's/ /./g' |
#----------------------------------------------------------------------#
# Delimit on dots... reformat so that the key is in front...           #
#----------------------------------------------------------------------#
awk -F. '{
  printf( "%s.%s.%s %s %s\n", $3, $4, $5, $6, $1 );
  }' |
while read key subnet domain; do
 
  if [[ $key != $prev_key ]]; then
    print $key
    prev_key=$key
  fi
 
  print $subnet PTR $domain.domain.com
 
done

If you have:

ip="192.168.1.2"

You can:

set `echo "$ip" | sed 's/\./ /g'`
revip=$4.$3.$2.$1.in-addr.arpa

But sheesh.. editing zone files?? Ever consider using dynamic updates to your BIND instead? A whole lot easier IMHO.

I know that's not exactly what you were looking for, but may take you there.