这是我的示例文本文件:
$ cat RealVNC\ MRU.reg
"10"="Lamborghini-:1"
"16"="Terminus-"
"20"="Midnighter-:5915"
"35"="ThreepWood-:1"
"81"="Midnighter-:1"
"58"="Midnighter-"
我想转换 第一个字段的值(""
之间的数字)从十进制到十六进制(它是Windows的.reg文件,所以我认为数字是十进制的,现在文件太长了,无法手动编辑。
我需要获得的示例结果:
$ cat Hex\ RealVNC\ MRU.reg
"0A"="Lamborghini-:1"
"10"="Terminus-"
"14"="Midnighter-:5915"
"23"="ThreepWood-:1"
"51"="Midnighter-:1"
"3A"="Midnighter-"
可以看出,只有数字已经改变。 结果数字必须是两个字符长(RegEdit认为它们不同) 行的变化不会在这里烦恼,但我认为它会更多"清洁"一个不会改变它的解决方案。
我不希望任何数字(十进制或十六进制)具有超过 2个字符,但考虑到这种可能性的解决方案将是最佳的(因为它更通用溶液)。
到目前为止我已经测试过:
$ cat RealVNC\ MRU.reg | awk -F \" '{print $2}'
10
16
20
35
81
58
但是我不知道谁在线改变从十进制到十六进制。
我的shell通常是Bash,但也接受其他shell派生的解决方案(如Perl或Python)。
答案 0 :(得分:3)
一个简单的awk
:
awk -F\" '$2=sprintf("%02X", $2)' OFS=\" file
"0A"="Lamborghini-:1"
"10"="Terminus-"
"14"="Midnighter-:5915"
"23"="ThreepWood-:1"
"51"="Midnighter-:1"
"3A"="Midnighter-"
<强>解释强>
-F\"
:将字段分隔符(FS
)设置为"
$2=sprintf("%02X", $2)
:$2
已分配给它打印
版本(sprintf
),使用十六进制的%02X
掩码
字母&#39; A&#39;到&#39; F&#39;对于大于9的十六进制数字和两位数
宽度0
填充
OFS=\"
:设置 O 输出 FS 以匹配 FS
$2
分配始终是 true ,并且不会给出其他操作,awk
始终会将结果显示为默认操作。
答案 1 :(得分:1)
你可以使用perl - 当substitution operator使用e
标志时,你可以传递一个函数来处理替换值:
echo abc | perl -ne 's/(.+)/uc($1);print/e' # ABC
然后,您可以使用sprintf
function通过%X
转换将十进制转换为十六进制:
%x an unsigned integer, in hexadecimal
%X like %x, but using upper-case letters
$ cat RealVNC\ MRU.reg | perl -ne 's/^"(.*?)"/sprintf("\"%X\"", $1)/e;print;'
"A"="Lamborghini-:1"
"10"="Terminus-"
"14"="Midnighter-:5915"
"23"="ThreepWood-:1"
"51"="Midnighter-:1"
"3A"="Midnighter-"
如果您想要0-F单值的前导零,您可以使用前缀格式%02X
:
%02X
^^L Conversion
|L Result length
L- Prefix char
结果:
$ cat RealVNC\ MRU.reg | perl -ne 's/^"(.*?)"/sprintf("\"%02X\"", $1)/e;print;'
"0A"="Lamborghini-:1"
"10"="Terminus-"
"14"="Midnighter-:5915"
"23"="ThreepWood-:1"
"51"="Midnighter-:1"
"3A"="Midnighter-"