Example: I have this netmask: 255.255.255.0
Is there, in bash, a command or a simple script to convert my netmask in notation /24?
Example: I have this netmask: 255.255.255.0
Is there, in bash, a command or a simple script to convert my netmask in notation /24?
Example Function for RHEL6/RHEL7:
IPprefix_by_netmask() {
#function returns prefix for given netmask in arg1
ipcalc -p 1.1.1.1 $1 | sed -n 's/^PREFIX=\(.*\)/\/\1/p'
}
The Result:
$ IPprefix_by_netmask 255.255.255.0
/24
In other Linux distributives ipcalc options may differ.
The same function without ipcalc, tested in Solaris and Linux:
IPprefix_by_netmask() {
#function returns prefix for given netmask in arg1
bits=0
for octet in $(echo $1| sed 's/\./ /g'); do
binbits=$(echo "obase=2; ibase=10; ${octet}"| bc | sed 's/0//g')
let bits+=${#binbits}
done
echo "/${bits}"
}
ipcalc
version of the function outputs nothing on my system, (Lubuntu v17.10). Running ipcalc -p 1.1.1.1 255.255.255.0
returns an "Unknown option: -p" error. ipcalc
version is 0.41-5. –
Mellifluous ipcalc -n 1.1.1.1 $1 | sed -n '/^Netm/{s#.*= #/#;s/ .*//p;q}'
–
Mellifluous ipcalc -nb 1.1.1.1 "$1" | sed -n '/Netmask/s/^.*=[ ]/\//p
–
Baneful Function using subnetcalc
:
IPprefix_by_netmask() {
subnetcalc 1.1.1.1 "$1" -n | sed -n '/^Netw/{s#.*/ #/#p;q}'
}
In pure bash
, (i.e. no external utils like sed
or bc
), convert IP to a long octal string and sum its bits:
IPprefix_by_netmask () {
c=0 x=0$( printf '%o' ${1//./ } )
while [ $x -gt 0 ]; do
let c+=$((x%2)) 'x>>=1'
done
echo /$c ; }
Output of IPprefix_by_netmask 255.255.255.0
(either function):
/24
ipcalc
and sipcalc
is a little better than that of subnetcalc
due to better availability, according to pkgs.org. You may wish to take this into account. –
Agrigento ipcalc
and sipcalc
in its official repo, while subnetcalc
is only available from the AUR; RHEL 8 and derivatives (with EPEL enabled) similarly have both ipcalc
and sipcalc
but not subnetcalc
. –
Agrigento Example Function for RHEL6/RHEL7:
IPprefix_by_netmask() {
#function returns prefix for given netmask in arg1
ipcalc -p 1.1.1.1 $1 | sed -n 's/^PREFIX=\(.*\)/\/\1/p'
}
The Result:
$ IPprefix_by_netmask 255.255.255.0
/24
In other Linux distributives ipcalc options may differ.
The same function without ipcalc, tested in Solaris and Linux:
IPprefix_by_netmask() {
#function returns prefix for given netmask in arg1
bits=0
for octet in $(echo $1| sed 's/\./ /g'); do
binbits=$(echo "obase=2; ibase=10; ${octet}"| bc | sed 's/0//g')
let bits+=${#binbits}
done
echo "/${bits}"
}
ipcalc
version of the function outputs nothing on my system, (Lubuntu v17.10). Running ipcalc -p 1.1.1.1 255.255.255.0
returns an "Unknown option: -p" error. ipcalc
version is 0.41-5. –
Mellifluous ipcalc -n 1.1.1.1 $1 | sed -n '/^Netm/{s#.*= #/#;s/ .*//p;q}'
–
Mellifluous ipcalc -nb 1.1.1.1 "$1" | sed -n '/Netmask/s/^.*=[ ]/\//p
–
Baneful While GNU awk is not Bash, it’s installed by default in enough distributions that this may be helpful in the sense of the question:
awk -F. '{
split($0, octets)
for (i in octets) {
mask += 8 - log(2**8 - octets[i])/log(2);
}
print "/" mask
}' <<< 255.255.255.240
This prints:
/28
2**8
with 2^8
, otherwise I got awk: line 4: syntax error at or near *
. However this is on Debian 12 which comes with mawk
. –
Magistery Based on Sasha's answer, this script works with dash
(tested with Ubuntu 18.04):
IPprefix_by_netmask() {
#function returns prefix for given netmask in arg1
bits=0
for octet in $(echo $1| sed 's/\./ /g'); do
binbits=$(echo "obase=2; ibase=10; ${octet}"| bc | sed 's/0//g')
bits=$(expr $bits + ${#binbits})
done
echo "/${bits}"
}
© 2022 - 2024 — McMap. All rights reserved.
import ipaddress,math;print("/" + str(32-math.ceil(math.log2(int(ipaddress.IPv4Address(input()))^2**32-1))))
– Pentothal