Awk 或 sed 在 mac 地址中添加缺失的零

Awk or sed to prepend missing zeros in mac addresses

我有一个由 IP 和 MAC 地址对组成的文件,我需要在每个八位字节中用零填充 MAC 地址,但我不想更改 IP .所以这个...

10.5.96.41 0:0:e:4c:b7:42
10.5.96.42 c4:f7:0:13:ef:32
10.5.96.43 0:e8:4c:60:2b:42
10.5.96.44 0:6a:bf:b:35:f1

应该改成这个...

10.5.96.41 00:00:0e:4c:b7:42
10.5.96.42 c4:f7:00:13:ef:32
10.5.96.43 00:e8:4c:60:2b:42
10.5.96.44 00:6a:bf:0b:35:f1

我试过 sed 's/\b\(\w\)\b/0/g' 但结果是:

10.05.96.41 00:00:0e:4c:b7:42
10.05.96.42 c4:f7:00:13:ef:32
10.05.96.43 00:e8:4c:60:2b:42
10.05.96.44 00:6a:bf:0b:35:f1

这是不需要的,因为我只想影响 MAC 地址部分。

由于您已标记 macos,我不确定这是否适合您。我在 GNU awk

上测试过
$ awk '{gsub(/\<[0-9a-f]\>/, "0&", )} 1' ip.txt
10.5.96.41 00:00:0e:4c:b7:42
10.5.96.42 c4:f7:00:13:ef:32
10.5.96.43 00:e8:4c:60:2b:42
10.5.96.44 00:6a:bf:0b:35:f1

awk适合字段处理,这里可以简单的只对第二个字段进行替换

但是,我在您的 sed 命令中看到 \b\w,所以您使用的是 GNU sed?如果是这样,

sed -E ':a s/( .*)(\b\w\b)//; ta' ip.txt


随着 perl

$ perl -lane '$F[1] =~ s/\b\w\b/0$&/g; print join " ", @F' ip.txt
10.5.96.41 00:00:0e:4c:b7:42
10.5.96.42 c4:f7:00:13:ef:32
10.5.96.43 00:e8:4c:60:2b:42
10.5.96.44 00:6a:bf:0b:35:f1

如果您想尝试一下,请指定您要避免替​​换第一个字段:

perl -pe 's/^\H+(*SKIP)(*F)|\b\w\b/0$&/g' ip.txt

使用 GNU sed:

sed -E ':a;s/([ :])(.)(:|$)//g;ta' file

使用任何 sed:

sed ':a;s/\([ :]\)\(.\):/:/g;ta' file

解释(GNU 版本)

:a  # a label called 'a', used as a jump target
;   # command separator
s   # substitute command ...
/([ :])(.)(:|$)/ # search for any single char which is enclosed by
                 # either two colons, a whitespace and a colon or
                 # a colon and the end of the line ($)
                 # Content between () will be matched in a group
                 # which is used in the replacement pattern

          # replacement pattern: group1 , a zero, group2 and 
                 # group3 (see above)
/g               # replace as often as possible
;                # command separator
ta               # jump back to a if the previous s command replaced
                 # something (see below)

需要使用标签 ata 命令的循环,因为如果输入已经是替换的一部分,sed 将不会再次匹配模式。例如,在这种情况下会发生这种情况(第一行):

0:0

当应用上述模式时,sed 将替换

<space>0: by <space>00: <- colon

同一个冒号将不会再次与第二个零的开头 : 匹配。因此,循环直到所有内容都被替换。

任何使用 -E 支持 ERE 的 sed,例如GNU sed 或 OSX/BSD (MacOS) sed:

$ sed -E 's/[ :]/&0/g; s/0([^:]{2}(:|$))//g' file
10.5.96.41 00:00:0e:4c:b7:42
10.5.96.42 c4:f7:00:13:ef:32
10.5.96.43 00:e8:4c:60:2b:42
10.5.96.44 00:6a:bf:0b:35:f1

和任何 sed:

$ sed 's/[ :]/&0/g; s/0\([^:][^:]:\)//g; s/0\([^:][^:]$\)//' file
10.5.96.41 00:00:0e:4c:b7:42
10.5.96.42 c4:f7:00:13:ef:32
10.5.96.43 00:e8:4c:60:2b:42
10.5.96.44 00:6a:bf:0b:35:f1

这可能适合您 (GNU sed):

sed 's/\b.\(:\|$\)/0&/g' file

在任何单个字符前加上 0,后跟 : 或行尾。

其他 seds 可能使用:

sed 's/\<.\(:\|$\)/0&/g' file