如何使用 awk 将 mac addr 转换为 int?
How to convert mac addr to int using awk?
输入:
192.168.0.1 aa:bb:cc:00:11:22 192.168.0.1 aa:00:bb:11:cc:22
192.168.10.11 2a:bb:cc:20:11:22 192.168.10.11 aa:02:bb:21:cc:22
输出:
3232235521 187723558162722 3232235521 186920115227682
3232238091 46986071904546 3232238091 186928706210850
我知道如何在 python3 中将 mac 转换为整数(十六进制 -> 整数)
: mac = int(mac.replace(':', ''), 16)
但我无法在 shell 中应用此方法。也不知道IP to Int.
我想像这样使用 awk:
awk '{,=??, ,=???}' tmpfile > newfile
对于 strtonum() 使用 GNU awk:
$ echo 'aa:bb:cc:00:11:22' | awk '{gsub(/:/,""); print strtonum("0x"[=10=])}'
187723558162722
$ echo '192.168.0.1' | awk '{split([=10=],o,/[.]/); print o[1]*256^3 + o[2]*256^2 + o[3]*256 + o[4]}'
3232235521
$ cat tst.awk
function ip2int(ip, o) { split(ip,o,/[.]/); return o[1]*256^3 + o[2]*256^2 + o[3]*256 + o[4] }
function mac2int(mac) { gsub(/:/,"",mac); return strtonum("0x"mac) }
{ print ip2int(), mac2int(), ip2int(), mac2int() }
$ awk -f tst.awk file
3232235521 187723558162722 3232235521 186920115227682
3232238091 46986071904546 3232238091 186928706210850
试试这个 Perl 单行代码
$ cat matii.txt
192.168.0.1 aa:bb:cc:00:11:22 192.168.0.1 aa:00:bb:11:cc:22
192.168.10.11 2a:bb:cc:20:11:22 192.168.10.11 aa:02:bb:21:cc:22
perl -pe ' s/(\d+)\.(\d+)\.(\d+).(\d+)/*256**3+*256**2+*256+/ge; s/://g ; s/\S+\s+\K(\S+)/hex()/ge;' matii.txt
3232235521 187723558162722 3232235521 186920115227682
3232238091 46986071904546 3232238091 186928706210850
Perl 相当于
mac = int(mac.replace(':', ''), 16)
是
$mac = hex( $max =~ s/://rg )
解决方案:
perl -nle'print join " ", unpack "N Q> N Q>", pack "( C4 xx(H2)6 )2", /[0-9a-fA-F]+/g'
更清晰的解决方案:
perl -lane'
sub ipv4_to_dec { unpack "N", pack "C4", split /\./, $_[0] }
sub mac_to_dec { hex( $_[0] =~ s/://rg ) }
print join " ",
ipv4_to_dec($F[0]), mac_to_dec($F[1]),
ipv4_to_dec($F[2]), mac_to_dec($F[3]);
'
或
perl -ple'
sub ipv4_to_dec { unpack "N", pack "C4", split /\./, $_[0] }
sub mac_to_dec { hex( $_[0] =~ s/://rg ) }
s{\G(\s*)(\S+)(\s+)(\S+)}{ . ipv4_to_dec() . . mac_to_dec() }eg;
'
输入:
192.168.0.1 aa:bb:cc:00:11:22 192.168.0.1 aa:00:bb:11:cc:22
192.168.10.11 2a:bb:cc:20:11:22 192.168.10.11 aa:02:bb:21:cc:22
输出:
3232235521 187723558162722 3232235521 186920115227682
3232238091 46986071904546 3232238091 186928706210850
我知道如何在 python3 中将 mac 转换为整数(十六进制 -> 整数)
: mac = int(mac.replace(':', ''), 16)
但我无法在 shell 中应用此方法。也不知道IP to Int.
我想像这样使用 awk:
awk '{,=??, ,=???}' tmpfile > newfile
对于 strtonum() 使用 GNU awk:
$ echo 'aa:bb:cc:00:11:22' | awk '{gsub(/:/,""); print strtonum("0x"[=10=])}'
187723558162722
$ echo '192.168.0.1' | awk '{split([=10=],o,/[.]/); print o[1]*256^3 + o[2]*256^2 + o[3]*256 + o[4]}'
3232235521
$ cat tst.awk
function ip2int(ip, o) { split(ip,o,/[.]/); return o[1]*256^3 + o[2]*256^2 + o[3]*256 + o[4] }
function mac2int(mac) { gsub(/:/,"",mac); return strtonum("0x"mac) }
{ print ip2int(), mac2int(), ip2int(), mac2int() }
$ awk -f tst.awk file
3232235521 187723558162722 3232235521 186920115227682
3232238091 46986071904546 3232238091 186928706210850
试试这个 Perl 单行代码
$ cat matii.txt
192.168.0.1 aa:bb:cc:00:11:22 192.168.0.1 aa:00:bb:11:cc:22
192.168.10.11 2a:bb:cc:20:11:22 192.168.10.11 aa:02:bb:21:cc:22
perl -pe ' s/(\d+)\.(\d+)\.(\d+).(\d+)/*256**3+*256**2+*256+/ge; s/://g ; s/\S+\s+\K(\S+)/hex()/ge;' matii.txt
3232235521 187723558162722 3232235521 186920115227682
3232238091 46986071904546 3232238091 186928706210850
Perl 相当于
mac = int(mac.replace(':', ''), 16)
是
$mac = hex( $max =~ s/://rg )
解决方案:
perl -nle'print join " ", unpack "N Q> N Q>", pack "( C4 xx(H2)6 )2", /[0-9a-fA-F]+/g'
更清晰的解决方案:
perl -lane'
sub ipv4_to_dec { unpack "N", pack "C4", split /\./, $_[0] }
sub mac_to_dec { hex( $_[0] =~ s/://rg ) }
print join " ",
ipv4_to_dec($F[0]), mac_to_dec($F[1]),
ipv4_to_dec($F[2]), mac_to_dec($F[3]);
'
或
perl -ple'
sub ipv4_to_dec { unpack "N", pack "C4", split /\./, $_[0] }
sub mac_to_dec { hex( $_[0] =~ s/://rg ) }
s{\G(\s*)(\S+)(\s+)(\S+)}{ . ipv4_to_dec() . . mac_to_dec() }eg;
'