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)
需要使用标签 a
和 ta
命令的循环,因为如果输入已经是替换的一部分,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
我有一个由 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)
需要使用标签 a
和 ta
命令的循环,因为如果输入已经是替换的一部分,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