将IP地址批量转换成小数?
Batch Convert IP Addresses into Decimals?
我有一个大文件,每行包含 2 IPs
- 总共大约有 300 万行。
这是文件示例:
1.32.0.0,1.32.255.255
5.72.0.0,5.75.255.255
5.180.0.0,5.183.255.255
222.127.228.22,222.127.228.23
222.127.228.24,222.127.228.24
我需要将每个 IP
转换为 IP Decimal
,如下所示:
18874368,18939903
88604672,88866815
95682560,95944703
3732923414,3732923415
3732923416,3732923416
我更喜欢通过命令行严格执行此操作的方法。只要不需要安装额外的模块,我就可以使用 perl
或 python
。
我以为我遇到过有人使用 sed
像这样转换 IPs
的方法,但似乎再也找不到该教程了。任何帮助将不胜感激。
这是 python
解决方案,仅使用标准模块 (re, sys):
import re
import sys
def multiplier_generator():
""" Cyclic generator of powers of 256 (from 256**3 down to 256**0)
The mulitpliers tupple could be replaced by inline calculation
of power, but this approach has better performance.
"""
multipliers = (
256**3,
256**2,
256**1,
256**0,
)
idx = 0
while 1 == 1:
yield multipliers[idx]
idx = (idx + 1) % 4
def replacer(match_object):
"""re.sub replacer for ip group"""
multiplier = multiplier_generator()
res = 0
for i in xrange(1,5):
res += multiplier.next()*int(match_object.group(i))
return str(res)
if __name__ == "__main__":
std_in = ""
if len(sys.argv) > 1:
with open(sys.argv[1],'r') as f:
std_in = f.read()
else:
std_in = sys.stdin.read()
print re.sub(r"([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)", replacer, std_in )
此解决方案替换了每个 ip 地址,这些地址可以在标准输入的文本中找到,也可以从作为第一个参数传递的文件中找到,即:
- python convert.py < input_file.txt, 或
- python convert.py file.txt 或
- echo "1.2.3.4, 5.6.7.8" | python convert.py.
如果您安装了 gnu awk(对于 RT
变量),您可以使用这个单行代码:
awk -F. -v RS='[\n,]' '{printf "%d%s", ((*256+)*256+)*256+, RT}' file
18874368,18939903
88604672,88866815
95682560,95944703
3732923414,3732923415
3732923416,3732923416
与bash:
ip2dec() {
set -- ${1//./ } # split with "." to
declare -i dec # set integer attribute
dec=*256*256*256+*256*256+*256+
echo -n $dec
}
while IFS=, read -r a b; do ip2dec $a; echo -n ,; ip2dec $b; echo; done < file
输出:
18874368,18939903
88604672,88866815
95682560,95944703
3732923414,3732923415
3732923416,3732923416
使用 bash 并使用移位(一个 CPU 指令)而不是乘法(很多指令):
ip2dec() { local IFS=.
set -- # split with "." to
printf '%s' "$((<<24+<<16+<<8+))"
}
while IFS=, read -r a b; do
printf '%s,%s\n' "$(ip2dec $a)" "$(ip2dec $b)"
done < file
我有一个大文件,每行包含 2 IPs
- 总共大约有 300 万行。
这是文件示例:
1.32.0.0,1.32.255.255
5.72.0.0,5.75.255.255
5.180.0.0,5.183.255.255
222.127.228.22,222.127.228.23
222.127.228.24,222.127.228.24
我需要将每个 IP
转换为 IP Decimal
,如下所示:
18874368,18939903
88604672,88866815
95682560,95944703
3732923414,3732923415
3732923416,3732923416
我更喜欢通过命令行严格执行此操作的方法。只要不需要安装额外的模块,我就可以使用 perl
或 python
。
我以为我遇到过有人使用 sed
像这样转换 IPs
的方法,但似乎再也找不到该教程了。任何帮助将不胜感激。
这是 python
解决方案,仅使用标准模块 (re, sys):
import re
import sys
def multiplier_generator():
""" Cyclic generator of powers of 256 (from 256**3 down to 256**0)
The mulitpliers tupple could be replaced by inline calculation
of power, but this approach has better performance.
"""
multipliers = (
256**3,
256**2,
256**1,
256**0,
)
idx = 0
while 1 == 1:
yield multipliers[idx]
idx = (idx + 1) % 4
def replacer(match_object):
"""re.sub replacer for ip group"""
multiplier = multiplier_generator()
res = 0
for i in xrange(1,5):
res += multiplier.next()*int(match_object.group(i))
return str(res)
if __name__ == "__main__":
std_in = ""
if len(sys.argv) > 1:
with open(sys.argv[1],'r') as f:
std_in = f.read()
else:
std_in = sys.stdin.read()
print re.sub(r"([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)", replacer, std_in )
此解决方案替换了每个 ip 地址,这些地址可以在标准输入的文本中找到,也可以从作为第一个参数传递的文件中找到,即:
- python convert.py < input_file.txt, 或
- python convert.py file.txt 或
- echo "1.2.3.4, 5.6.7.8" | python convert.py.
如果您安装了 gnu awk(对于 RT
变量),您可以使用这个单行代码:
awk -F. -v RS='[\n,]' '{printf "%d%s", ((*256+)*256+)*256+, RT}' file
18874368,18939903
88604672,88866815
95682560,95944703
3732923414,3732923415
3732923416,3732923416
与bash:
ip2dec() {
set -- ${1//./ } # split with "." to
declare -i dec # set integer attribute
dec=*256*256*256+*256*256+*256+
echo -n $dec
}
while IFS=, read -r a b; do ip2dec $a; echo -n ,; ip2dec $b; echo; done < file
输出:
18874368,18939903 88604672,88866815 95682560,95944703 3732923414,3732923415 3732923416,3732923416
使用 bash 并使用移位(一个 CPU 指令)而不是乘法(很多指令):
ip2dec() { local IFS=.
set -- # split with "." to
printf '%s' "$((<<24+<<16+<<8+))"
}
while IFS=, read -r a b; do
printf '%s,%s\n' "$(ip2dec $a)" "$(ip2dec $b)"
done < file