Search code examples
bashhexip-address

Bash Hex to Dec IP conversion in a file


I have a file that has hundreds of lines that look similar to this:

index.=10200,intf.10200.4=eth1,vlan.10200.4=500,IP-Addr.10200.4=C0A80A78,uptime.10200.4=120days,duplex.10200.4=full,status.10200.4=up
index.=10201,intf.10201.25=eth1,vlan.10201.25=500,IP-Addr.10201.25=C0A80A79,uptime.10201.25=80days,duplex.10201.25=full,status.10201.25=up
index.=10202,intf.10202.6=eth1,vlan.10202.6=500,IP-Addr.10202.6=C0A80A80,uptime.10202.6=240days,duplex.10202.6=full,status.10202.6=up

I am trying to convert all the Hexadecimal IP address to Dotted Decimal by editing the file in place. I have seen all the bash hex to dec ip converters online, but those are for entering a value then converting.

How would I go about editing values in place in a file?

More detailed data set:

index.=10200,CDP-Local-Intf.10200=FastEthernet0/0/1,CDP-IP-Addr.10200.44=C0A80A78,CDP-Uptime.10200.44=Timeticks:(342342322)52days,CDP-Opposite-Intf.10200.44=FastEthernet0/1/0,CDP-VLAN.10200.44=100,CDP-Duplex.10200.44=3,CDP-Other.10200.44=00000032
index.=10201,CDP-Local-Intf.10201=FastEthernet2/0/1,CDP-IP-Addr.10201.25=C0A80A79,CDP-Uptime.10201.25=Timeticks:(342342322)52days,CDP-Opposite-Intf.10201.25=FastEthernet0/2/0,CDP-VLAN.10201.25=101,CDP-Duplex.10201.25=3,CDP-Other.10201.25=00000032
index.=10202,CDP-Local-Intf.10202=FastEthernet2/1/1,CDP-IP-Addr.10202.11=C0A80A80,CDP-Uptime.10202.11=Timeticks:(342342322)52days,CDP-Opposite-Intf.10202.11=FastEthernet0/3/0,CDP-VLAN.10202.11=101,CDP-Duplex.10202.11=3,CDP-Other.10202.11=00000032

Solution

  • If perl is your option, would you try the following:

    perl -i -pe 's/(CDP-IP-Addr[\d.]+=)([[:xdigit:]]{8})/$1 . join(".", unpack("C4", pack("H8", $2)))/e' datafile
    
    • The -i option to perl enables the in-place editing.
    • The -pe option tells perl to process the input file line by line as sed or awk does.
    • The regex (CDP-IP-Addr[\d.]+=)([[:xdigit:]]{8}) extracts the substring "CDP-IP-Addr.xx.xx=" and the following hexadecimal string. They are captured by $1 and $2 in order.
    • The function unpack("C4", pack("H8", $2)) converts the 8-digit hexadecimal string $2 into an array of four decimal values.
    • The e switch to the s/regex/replacement/ operator tells perl to evaluate the replacement as a perl expression.