输入:
dmesg | grep [0-9][0-9]:[0-9][0-9]
f0:de:f1:11:22:33
...
输出:
dmesg | SOMEMAGIC | grep [0-9][0-9]:[0-9][0-9]
f0:de:f1:52:22:17
...
我是如何得到“52:22:17”的?
echo 11:22:33 | cksum | sed "s/.\{2\}/&:/g" | cut -d: -f-3
52:22:17
通过这种方式,当我必须给出输出时,我可以“审查”我的 MAC 地址 NIC 特定字符串dmesg
。 (“SOMEMAGIC”是一个神奇的东西,它可以自动为所有可以在dmesg
AND 保留(NIC 特定字符串,只需将其替换为另一个字符串)中找到的 MAC 执行此操作,例如:wlan0 MAC 是 X,wlan1 MAC是 Y)
问题:如何从输出中审查 MAC 地址的 NIC 特定字符串dmesg
,但保留可能存在多个不同的 MAC 地址?
UPDATE#1:以“我的”方式,如示例所示,我们可以生成一个包含约 1600 万行的表 (16*16 * 16*16 * 16*16 = 16^2 = 16 777 216) - 所以它是不好,因为它可以找出原来的 MAC 是什么!
UPDATE#2:解决方案必须不区分大小写,因此 MAC 是大写还是小写都没有关系
答案1
对于grep
不区分大小写的 mac 地址,为了获得更好的匹配,您应该扩展模式以匹配十六进制值,并减少正数匹配所有 6 对十六进制字符:
dmesg | grep -i [0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]
取代任何可以出现多次的 MAC 的数量,其中随机的一个,以及随机的绝不匹配一个(其他)MAC,你必须首先知道 dmesg 输出文本中出现的所有不同 MAC,假设这是一个列表 L。然后将 L 中的每个元素映射到 L 中未出现的随机 MAC,并根据映射替换每个MAC地址。
我什至不是一个初学者awk
,但我认为上面这些要求已经超出了它的能力。我会认真考虑在 python/ruby/perl 中做这样的事情。
但是,如果输出中只有 MAC 地址dmesg
且设置了全局唯一 OUI(组织唯一标识符)位,则可能有捷径。这些是在第一个十六进制字符中设置了位一 (1) 的字符(即值为2
, 3
, 6
, 7
, a
, b
, e
, f
)。这对于正式发布的硬件来说是正常的。如果是这种情况,您可以将每个 MAC 地址映射到“本地管理”MAC 地址(清除第 1 位),而不必担心您的随机 MAC 地址(清除第 1 位)恰好与现有 MAC 地址匹配。在这种情况下,您只需保留映射(对于文件后期发生的情况),而不是缓冲可能与真实 MAC 发生的随机冲突。
此限制可能足以简化程序,例如awk
能够实现您的要求(假设它们在更严格的情况下无法实现)。
请注意,六字节 MAC-48 的使用已被八字节 EUI-64 标识符“扩展”。我自己还没有看到这些,但它们可能会出现在您的dmesg
输出中。
一个处理困难情况的 python 程序:
#! /usr/bin/env python
# coding: utf-8
import sys
import re
import io
from random import randint
MAC48_REGEX = re.compile(r"""
(?x)(?i) # free spacing mode, ignore case
([0-9A-F]{2}[:-]){5} # five times two hex-characters, followed by : or -
([0-9A-F]{2}) # final two hex-characters
""")
class MatchMAC48(object):
MAX_MAC = 256 ** 6 - 1
def __init__(self):
self._mac_map = {}
self._buffer = io.StringIO()
def __call__(self, line):
"""analyse the input for input MAC addresses and store them"""
self._buffer.write(line)
res = MAC48_REGEX.search(line)
if not res:
return line # no MACs
index = 0
while res:
self._mac_map[res.group()] = None
index += res.span()[1]
res = MAC48_REGEX.search(line[index:])
def generate_map(self):
"""generate a unique mapping MAC for each of the MAC address keys"""
for k in self._mac_map:
if self._mac_map[k] is not None:
continue
r = None
while (r is None or
r in self._mac_map or # not an original MAC
r in self._mac_map.values()): # twice the same random MAC
r = randint(0, self.MAX_MAC)
ml = []
for i in range(6):
ml.insert(0, u'{:02x}'.format(r & 255))
r >>= 8
self._mac_map[k] = u':'.join(ml)
def dump(self, fp=sys.stdout):
"""dump the cached StringIO buffer"""
mm48.generate_map() # in case not yet generated
x = self._buffer.getvalue()
for k in self._mac_map:
x = x.replace(k, self._mac_map[k])
fp.write(x)
mm48 = MatchMAC48()
for line in sys.stdin:
mm48(line.decode('utf-8'))
mm48.dump()