例子:
输入:
0x12345678 0aef1234 0098adefa 123456789
预期输出:
0x00000000 00000000 0098adefa 123456789
尝试过这个:
sed -E "s/[0-9a-fA-F]{8}/00000000/g"
但即使有超过 8 个连续的十六进制数字,也会被替换。
答案1
您可以使用单词边界\b
来标记单词的开头或结尾,此外还需要考虑到 可以0x
在数字前面:
sed -E 's/\b(0x|)[0-9a-fA-F]{8}\b/\100000000/g'
尽管如此,还是有一些特殊情况,您需要考虑如何处理它们,例如00x12345678
,在上面的模式中,它没有被替换。
答案2
在 Perl 中,您可以使用“环视断言”,即您可以说“前面没有十六进制数字”和“后面没有十六进制数字”:
perl -pe 's/(?<![0-9a-fA-F])[0-9a-fA-F]{8}(?![0-9a-fA-F])/00000000/g'
环视不计入匹配的字符串,即它们不会被替换,并且可以匹配多次(一次在后视中,一次在前视中)。
您还可以使用[:xdigit:]
POSIX 类代替0-9a-fA-F
.
答案3
$ echo '0x12345678 0aef1234 0098adefa 123456789' | sed -E 's/(\<|x)[[:xdigit:]]{8}\>/\100000000/g'
0x00000000 00000000 0098adefa 123456789
$ echo '12345678 0aef1234 0098adefa 123456789' | sed -E 's/(\<|x)[[:xdigit:]]{8}\>/\100000000/g'
00000000 00000000 0098adefa 123456789
正则表达式
(\<|x)[[:xdigit:]]{8}\>
将匹配八位长的十六进制数。它应该是一个完整的单词,或者前面带有x
。前面的字符(x
如果有的话,则为 )将被保存并插入到替换中的零之前。