Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

If we have this string (IP address): 192.168.1.1

How can I derive the (DNS reverse record form) from this string, so it will be shown like 1.1.168.192.in-addr.arpa using a shell script?

share|improve this question
    
It has to be with the shell? –  Braiam May 30 at 22:07
    
Stop doing that –  Michael Mrozek Jun 8 at 8:30

13 Answers 13

up vote 24 down vote accepted

You can do it with AWK. There are nicer ways to do it, but this is the simplest, I think.

echo '192.168.1.1' | awk 'BEGIN{FS="."}{print $4"."$3"."$2"."$1".in-addr.arpa"}'

This will reverse the order of the IP address.

Just to save a few keystrokes, as Mikel suggested, we can further shorten the upper statement:

echo '192.168.1.1' | awk -F . '{print $4"."$3"."$2"."$1".in-addr.arpa"}'

OR

echo '192.168.1.1' | awk -F. '{print $4"."$3"."$2"."$1".in-addr.arpa"}'

OR

echo '192.168.1.1' | awk -F. -vOFS=. '{print $4,$3,$2,$1,"in-addr.arpa"}'

AWK is pretty flexible. :)

share|improve this answer
    
If you want to save a few keystrokes, -F . should be equivalent to BEGIN{FS="."}. –  Mikel May 30 at 22:03
    
Thanks, it worked I will mark the question as answered –  Networker May 30 at 22:04

Just for curiosity value... using tac from GNU coreutils: given a variable ip in the form 192.168.1.1 then

$(printf %s "$ip." | tac -s.)in-addr.arpa

i.e.

$ ip=192.168.1.1
$ rr=$(printf %s "$ip." | tac -s.)in-addr.arpa
$ echo "$rr"
1.1.168.192.in-addr.arpa
share|improve this answer
5  
+1 This is definitely my favorite answer here. Thanks for introducing me to tac! –  Jonathon Reinhart May 31 at 17:41
    
Thanks are also due to @StéphaneChazelas for the elegant printf edit (I originally posted an ugly echo -n) –  steeldriver Jun 1 at 17:07

If you want to use only shell (zsh, ksh93, bash), here's another way:

IFS=. read w x y z <<<'192.168.1.1'
printf '%d.%d.%d.%d.in-addr.arpa.' "$z" "$y" "$x" "$w"

Or in plain old shell:

echo '192.168.1.1' | { IFS=. read w x y z; echo "$z.$y.$w.$x.in-addr.arpa."; }
share|improve this answer

Easily with Perl, thusly:

$ echo 192.168.1.1|perl -nle 'print join ".",reverse(split /\./,$_)'
1.1.168.192
share|improve this answer
6  
Can be made even more compact: perl -F'\.' -lane '$,=".";print reverse @F' –  Joseph R. May 30 at 22:15

To round it out, Ruby:

ruby -e 'require "ipaddr"; print IPAddr.new(ARGV.shift).reverse' 192.168.1.1

Which also supports IPv6

share|improve this answer

With zsh:

$ ip=192.168.1.1
$ echo ${(j:.:)${(s:.:Oa)ip}}.in-addr.arpa
1.1.168.192.in-addr.arpa

Those are variable expansion flags:

  • s:.:: split on .
  • Oa: reverse order the array
  • j:.:: join on .
share|improve this answer

Through GNU sed,

sed -r 's/^([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3})$/\4.\3.\2.\1.in-addr.arpa/g' file

It reverses any IPv4-address format.

Example:

$ echo '192.168.1.1' | sed -r 's/^([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3})$/\4.\3.\2.\1.in-addr.arpa/g'
1.1.168.192.in-addr.arpa

$ echo '192.1.1.1' | sed -r 's/^([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3})$/\4.\3.\2.\1.in-addr.arpa/g'
1.1.1.192.in-addr.arpa

$ echo '1.1.1.1' | sed -r 's/^([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3})$/\4.\3.\2.\1.in-addr.arpa/g'
1.1.1.1.in-addr.arpa

$ sed -r 's/^([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3})$/\4.\3.\2.\1.in-addr.arpa/g' <<< '192.168.189.23'
23.189.168.192.in-addr.arpa
share|improve this answer

Another possibility is to use the "dig" command line tool with the "-x" switch.

It actually does a request on the PTR entry, but if you filter on "PTR" it will show you one commented line (the request) and maybe some replies.

Using "dig" can be handy for a quick writing of the PTR name, without having to write a small script. Particularly if you need it interactively (to cut and paste the result). It works on IPv6 too.

share|improve this answer

If you want it working with IPv6 as well, you can use dig -x.

For example:

$ dig -x 194.68.208.240 | egrep '^;.*PTR$' | cut -c 2- | awk '{print $1}'
240.208.68.194.in-addr.arpa.

$ dig -x 2001:db8:dc61:2a61::1 | egrep '^;.*PTR$' | cut -c 2- | awk '{print $1}'
1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.6.a.2.1.6.c.d.8.b.d.0.1.0.0.2.ip6.arpa.
share|improve this answer
$ while read ip
while> do
while> n=( $(echo $ip) ) && echo "${n[4]}"'.'"${n[3]}"'.'"${n[2]}"'.'"${n[1]}"'.'"in-addr.arpa"
while> done
192.168.1.2
2.1.168.192.in-addr.arpa

This way you can type in an address and hit return for your result.

share|improve this answer

With host command from dnsutils:

$ host -t ptr 192.168.1.1 | cut -d' ' -f 2
1.1.168.192.in-addr.arpa.
share|improve this answer

In Python

 a = "192.168.1.122"
 import re
 m = re.search(r'(\d+)\.(\d+)\.(\d+)\.(\d+)',a)
 ip = m.group(4),m.group(3),m.group(2),m.group(1)
 '.'.join(ip) + ".in-addr.arpa"
 '122.1.168.192.in-addr.arpa'
share|improve this answer
    
Or more idiomatically, "{}.in-addr.arpa".format(".".join(reversed(a.split(".")))) in Python2.7 –  1_CR Jun 8 at 11:42
IFS=. ; set -- ${0+192.168.1.2}
printf %b. $4 $3 $2 $1 in-addr.arpa\\c

IFS=. ; printf %s\\n \
    in-addr.arpa ${0+192.168.1.2} |    
sed '1!G;$s/\n/./gp;h;d'

IFS=. ; printf '[%b.] ' \
    ${0+192.168.1.2.]PPPPP\\c} |dc
echo in-addr.arpa
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.