Bash 文件中的十六进制到十进制 IP 转换
Bash Hex to Dec IP conversion in a file
我有一个包含数百行的文件,看起来与此类似:
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
我正在尝试通过就地编辑文件将所有十六进制 IP 地址转换为点分十进制。
我在网上看到了所有 bash 十六进制到十进制 ip 的转换器,但那些是用于输入值然后转换的。
我该如何编辑文件中的值?
更详细的数据集:
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
不确定这是否有帮助,但如果您不介意使用 Python 进行快速转换,请查看这个 link 我发现它非常简单 Python将十六进制转换为十进制的脚本。
http://pythonldap.blogspot.com/2014/09/python-script-to-convert-hexadecimal.html
如果您需要转换十六进制文件,请尝试添加一个 for 循环以遍历十六进制值并将该文件用作您的参数。
这是 gawk
测试工具 - 它使用 gawk
特定功能和扩展。
$ cat tst.awk
match([=10=],/.*=([[:xdigit:]]+),(CDP-Uptime|uptime).*/,a) {
str = strtonum(sprintf("0x%s", a[1]))
ip=sprintf ("%d.%d.%d.%d",
rshift(and(str,0xff000000),24),
rshift(and(str,0x00ff0000),16),
rshift(and(str,0x0000ff00),08),
rshift(and(str,0x000000ff),00))
[=10=]=substr([=10=],1,a[1,"start"]-1) ip substr([=10=],a[1,"start"]+a[1,"length"])
}
1
$ gawk -f tst.awk myFile myMoreDetailedFile
index.=10200,intf.10200.4=eth1,vlan.10200.4=500,IP-Addr.10200.4=192.168.10.120,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=192.168.10.121,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=192.168.10.128,uptime.10202.6=240days,duplex.10202.6=full,status.10202.6=up
index.=10200,CDP-Local-Intf.10200=FastEthernet0/0/1,CDP-IP-Addr.10200.44=192.168.10.120,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=192.168.10.121,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=192.168.10.128,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
这绝对可以进一步简化。
试一试!
如果 perl
是您的选择,您会尝试以下操作吗:
perl -i -pe 's/(CDP-IP-Addr[\d.]+=)([[:xdigit:]]{8})/ . join(".", unpack("C4", pack("H8", )))/e' datafile
perl
的 -i
选项启用就地编辑。
-pe
选项告诉 perl 逐行处理输入文件
sed
或 awk
是。
- 正则表达式
(CDP-IP-Addr[\d.]+=)([[:xdigit:]]{8})
提取子串
"CDP-IP-Addr.xx.xx=" 和后面的十六进制字符串。他们是
按顺序被 </code> 和 <code>
捕获。
- 函数
unpack("C4", pack("H8", ))
将8位十六进制转换
将字符串 </code> 转换为四个十进制值的数组。</li>
<li> <code>e
切换到 s/regex/replacement/
运算符告诉 perl
将替换计算为 perl 表达式。
我有一个包含数百行的文件,看起来与此类似:
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
我正在尝试通过就地编辑文件将所有十六进制 IP 地址转换为点分十进制。 我在网上看到了所有 bash 十六进制到十进制 ip 的转换器,但那些是用于输入值然后转换的。
我该如何编辑文件中的值?
更详细的数据集:
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
不确定这是否有帮助,但如果您不介意使用 Python 进行快速转换,请查看这个 link 我发现它非常简单 Python将十六进制转换为十进制的脚本。
http://pythonldap.blogspot.com/2014/09/python-script-to-convert-hexadecimal.html
如果您需要转换十六进制文件,请尝试添加一个 for 循环以遍历十六进制值并将该文件用作您的参数。
这是 gawk
测试工具 - 它使用 gawk
特定功能和扩展。
$ cat tst.awk
match([=10=],/.*=([[:xdigit:]]+),(CDP-Uptime|uptime).*/,a) {
str = strtonum(sprintf("0x%s", a[1]))
ip=sprintf ("%d.%d.%d.%d",
rshift(and(str,0xff000000),24),
rshift(and(str,0x00ff0000),16),
rshift(and(str,0x0000ff00),08),
rshift(and(str,0x000000ff),00))
[=10=]=substr([=10=],1,a[1,"start"]-1) ip substr([=10=],a[1,"start"]+a[1,"length"])
}
1
$ gawk -f tst.awk myFile myMoreDetailedFile
index.=10200,intf.10200.4=eth1,vlan.10200.4=500,IP-Addr.10200.4=192.168.10.120,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=192.168.10.121,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=192.168.10.128,uptime.10202.6=240days,duplex.10202.6=full,status.10202.6=up
index.=10200,CDP-Local-Intf.10200=FastEthernet0/0/1,CDP-IP-Addr.10200.44=192.168.10.120,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=192.168.10.121,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=192.168.10.128,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
这绝对可以进一步简化。 试一试!
如果 perl
是您的选择,您会尝试以下操作吗:
perl -i -pe 's/(CDP-IP-Addr[\d.]+=)([[:xdigit:]]{8})/ . join(".", unpack("C4", pack("H8", )))/e' datafile
perl
的-i
选项启用就地编辑。-pe
选项告诉 perl 逐行处理输入文件sed
或awk
是。- 正则表达式
(CDP-IP-Addr[\d.]+=)([[:xdigit:]]{8})
提取子串 "CDP-IP-Addr.xx.xx=" 和后面的十六进制字符串。他们是 按顺序被</code> 和 <code>
捕获。 - 函数
unpack("C4", pack("H8", ))
将8位十六进制转换 将字符串</code> 转换为四个十进制值的数组。</li> <li> <code>e
切换到s/regex/replacement/
运算符告诉 perl 将替换计算为 perl 表达式。