bash 如何在bash中有效地将long int转换为dotted quad IP

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3222379/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 22:19:02  来源:igfitidea点击:

How to efficiently convert long int to dotted quad IP in bash

mysqlbash

提问by Mark

I have a lot of IP addresses in a large mysql DB stored as long int's. I need an efficient/quick way to convert them back to an IP within a BASH shell script ( or have mysql return the results as an IP?? ).

我在一个大的 mysql 数据库中有很多 IP 地址,它们存储为 long int。我需要一种高效/快速的方法将它们转换回 BASH shell 脚本中的 IP(或者让 mysql 将结果作为 IP 返回??)。

Note: specifically don't want to call perl, awk, or other 'language'.

注意:特别不想调用 perl、awk 或其他“语言”。

回答by Paused until further notice.

Since you asked for Bash:

既然你要求 Bash:

INET_NTOA() { 
    local IFS=. num quad ip e
    num=
    for e in 3 2 1
    do
        (( quad = 256 ** e))
        (( ip[3-e] = num / quad ))
        (( num = num % quad ))
    done
    ip[3]=$num
    echo "${ip[*]}"
}

INET_ATON ()
{
    local IFS=. ip num e
    ip=()
    for e in 3 2 1
    do
        (( num += ip[3-e] * 256 ** e ))
    done
    (( num += ip[3] ))
    echo "$num"
}

Examples:

例子:

$ INET_ATON 10.2.1.255
167903743
$ INET_NTOA 167903743
10.2.1.255

Here is a version that will work in any of the Bourne-derived shells I tried including dash, ksh, several versions of Bash, BusyBox ash, zsh (with -y) and even the Heirloom Bourne Shell.

这是一个可以在我尝试过的任何 Bourne 派生 shell 中使用的版本,包括 dash、ksh、多个版本的 Bash、BusyBox ash、zsh(带有-y),甚至是Heirloom Bourne Shell

INET_NTOA() {
    num=
    ip=
    for e in 3 2 1
    do
        quad=`echo "256 ^ $e" | bc`
        if [ -n "$ip" ]
        then
            ip=$ip.
        fi
        ip=$ip`echo "$num / $quad" | bc`
        num=`echo "$num % $quad" | bc`
    done
    ip=$ip.$num
    echo "$ip"
}

INET_ATON ()
{
    num=0
    e=3
    saveIFS=$IFS
    IFS=.
    set -- 
    IFS=$saveIFS
    for ip in "$@"
    do
        num=`echo "$num + $ip * 256 ^ $e" | bc`
        e=`echo "$e - 1" | bc`
    done
    echo "$num"
}

回答by Luká? Lalinsky

See the INET_NTOAfunction, you can use that to convert the number to an IP on the MySQL server.

查看INET_NTOA函数,您可以使用该函数将数字转换为 MySQL 服务器上的 IP。

回答by Daniel Podolsky

INET_ATON()
  {
  local IFS=. ipStr

  ipStr=()
  echo $(($(($(($(($(($((${ipStr[0]} * 256)) + ${ipStr[1]})) * 256)) + ${ipStr[2]})) * 256)) + ${ipStr[3]}))
  }

INET_NTOA()
  {
  echo "$(( / 16777216)).$(($(( % 16777216)) / 65536)).$(($(( % 65536)) / 256)).$(( % 256))"
  }

subnetRange()
  {
  local addr=$(INET_ATON "") mask=$(INET_ATON "")

  echo "$(INET_NTOA $(($addr & $mask))) $(INET_NTOA $(($addr | $mask ^ 4294967295)))"
  }


回答by barush

Given that the original question was about an efficientway to do this in bash, I think these might be worthy entries in the contest:

鉴于最初的问题是关于在 bash 中执行此操作的有效方法,我认为这些可能是比赛中有价值的条目:

INET_ATON()
  {
  local IFS=. ip
  ip=($*)
  echo $(((ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3]))
  }

INET_NTOA()
  {
  echo $(( >> 24)).$((( >> 16) % 256)).$((( >> 8) % 256)).$(( % 256))
  }

Naturally, these have the same "wrapping" problem as the other solutions given here, due to the shell's treatment of integers as signed.

自然地,由于 shell 将整数处理为有符号整数,这些问题与此处给出的其他解决方案具有相同的“包装”问题。

回答by Jesse Dhillon

Suppose you have a field called ip_addrin a table called hosts

假设您在名为ip_addr的表中调用了一个字段hosts

Then

然后

select INET_NTOA(ip_addr) from hosts;

Would do the query and return dotted quad IPs in the result set.

将执行查询并在结果集中返回点四边形 IP。

回答by digitalmechanic

i'm lazy, and this has already been done. So from a shell

我很懒,这已经完成了。所以从壳

$ ping -c1 1199092913 | head -n1 | grep -Eow "[0-9]+[.][0-9]+[.][0-9]+[.][0-9]+"

i'm sure there are other clever ways to do it from shell as well.

我相信还有其他聪明的方法可以从 shell 中做到这一点。