【问题标题】:Bash Hex to Dec IP conversion in a file文件中的 Bash Hex 到 Dec IP 转换
【发布时间】:2021-03-31 14:48:49
【问题描述】:

我有一个文件,其中有数百行与此类似:

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 hex to dec 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

【问题讨论】:

  • this thread 帮忙吗?
  • 我不确定,该线程是一个文件,其中每一行都是一个 IP。另外,该帖子在十六进制 IP 地址之前也有静态字符串,我的文件在索引 (10200.) 和 = 之间有随机数
  • 这意味着“提示”如何做到这一点,而不是作为一个完整的解决方案。我相信这种技术可以非常简单地用于您的案例。祝你好运!
  • 该解决方案不将输出打印到屏幕上吗?我正在尝试用十进制格式替换文件中的每个十六进制值
  • 该帖子代码确实有效,但它没有就地编辑文件。我可以在任何地方找到转换脚本,我的问题是“就地编辑文件”

标签: bash hex ip-address


【解决方案1】:

如果perl 是您的选择,您会尝试以下方法:

perl -i -pe 's/(CDP-IP-Addr[\d.]+=)([[:xdigit:]]{8})/$1 . join(".", unpack("C4", pack("H8", $2)))/e' datafile
  • perl-i 选项启用就地编辑。
  • -pe 选项告诉 perl 将输入文件逐行处理为 sedawk 可以。
  • 正则表达式(CDP-IP-Addr[\d.]+=)([[:xdigit:]]{8}) 提取子字符串 "CDP-IP-Addr.xx.xx=" 和以下十六进制字符串。他们是 依次被$1$2 捕获。
  • 函数unpack("C4", pack("H8", $2))转换8位十六进制 将字符串$2 转换为四个十进制值的数组。
  • e 切换到 s/regex/replacement/ 运算符告诉 perl 将替换作为 perl 表达式进行计算。

【讨论】:

    【解决方案2】:

    不确定这是否会有所帮助,但如果您不介意使用 Python 进行快速转换,请查看我找到的这个链接,其中包含一个非常简单的 Python 脚本来将十六进制转换为十进制。

    http://pythonldap.blogspot.com/2014/09/python-script-to-convert-hexadecimal.html

    如果您需要转换十六进制文件,请尝试添加一个 for 循环来遍历十六进制值并将该文件用作您的参数。

    【讨论】:

    • 文件格式化是通过 bash 脚本完成的,我只是想再添加几行来将所有十六进制 IP 转换为十进制 IP。如我的帖子所示,该文件在特定字段中包含十六进制,我不确定如何在文件中查找和替换。
    • 哇,看书要戴眼镜哈哈!让我看看一些 BASH 选项。抱歉!
    【解决方案3】:

    这是 gawk 测试工具 - 它使用 gawk 特定功能和扩展。

    $ cat tst.awk
    match($0,/.*=([[: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))
      $0=substr($0,1,a[1,"start"]-1) ip substr($0,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
    

    这绝对可以进一步简化。 试一试!

    【讨论】:

    • 我不确定出了什么问题,但它运行没有错误,但我没有看到文件中有任何变化。
    • 啊,我忘了最后的1。它可以工作,但是有没有办法让它修改文件?
    • @ehammer,到目前为止它不会修改原始文件 - 它只是输出到标准输出。首先检查输出,然后在满意后您可以修改原始文件 - 这应该是您最不担心的......
    • 如果这个命令被集成到一个 bash 脚本中会是什么样子?会不会只是 awk match () {}?
    • 我不太记得何时引入了 inplace gawk 扩展,但您可以尝试:1:gawk -i inplace -f tst.awk myFile 或者如果不支持/安装 inplace:2。@ 987654327@
    猜你喜欢
    • 2020-09-12
    • 2011-07-03
    • 2013-02-11
    • 1970-01-01
    • 1970-01-01
    • 2020-02-10
    • 1970-01-01
    • 2021-01-31
    • 2015-06-21
    相关资源
    最近更新 更多