我正在尝试转换第 3 列,如下所示。我可以使用此功能来
convert ***awk '{print $3}' | awk -F: '{printf("%02s:%02s:%02s:%02s:%02s:%02s\n",$1,$2,$3,$4,$5,$6)}'*** but how to get it to replace the 3rd column values.
Before
ABC 22.22.28.97 0:0:c:9f:f0:d9
ABC 22.22.28.109 0:50:56:64:49:f3
ABC 22.22.28.110 0:50:56:68:55:8e
After
ABC 22.22.28.97 00:00:0c:9f:f0:d9
ABC 22.22.28.109 00:50:56:64:49:f3
ABC 22.22.28.110 00:50:56:68:55:8e
谢谢 :)
答案1
我思考你问的是如何用零填充第三个字段中冒号分隔字符串的十六进制元素。这(可能令人惊讶地)很难做到,awk
因为:
- (字符串)格式
%s
说明符不支持零填充(awk
据我所知,无论是在 C 函数中还是在底层 C 函数中)
和
- 如果你使用适当的数字格式,
%02x
那么参数将被隐式转换十进制数字首先(将 af 作为垃圾丢弃)——导致不正确的十六进制值。
如果您有 GNU awk,则可以使用命令--non-decimal-data
行选项操作和转换十六进制数字,但是元素本身需要加上前缀才能0x
强制转换。例如
gawk --non-decimal-data '
gsub(/[[:xdigit:]][[:xdigit:]]?/,"0x&",$3) && split($3,a,":") {
$3=sprintf("%02x:%02x:%02x:%02x:%02x:%02x",a[1],a[2],a[3],a[4],a[5],a[6])
} 1' OFS='\t' file
ABC 22.22.28.97 00:00:0c:9f:f0:d9
ABC 22.22.28.109 00:50:56:64:49:f3
ABC 22.22.28.110 00:50:56:68:55:8e
perl
你可以使用hex
函数和简单的正则表达式替换,这有点简单:
perl -alne '$F[2] =~ s/([[:xdigit:]]{1,2})/sprintf "%02x", hex($1)/ge , print join "\t", @F' file
ABC 22.22.28.97 00:00:0c:9f:f0:d9
ABC 22.22.28.109 00:50:56:64:49:f3
ABC 22.22.28.110 00:50:56:68:55:8e
答案2
我找到了一个更简单的答案“s/\b(\w)\b/0\1/g”文件。我想使用 awk,但 sed 有 \b(在单词字符和非单词字符之间)
答案3
perl -pe 's/\b([0-9a-f](:|$))/0$1/g' ex
- 在所有单数十六进制数字前添加一个,
0
后跟“:”或行尾