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
How to efficiently convert long int to dotted quad IP in bash
提问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
回答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 中做到这一点。

