这是我的示例文本文件:
$ 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
但我不知道该内联谁从 dec 更改为十六进制。
我的 shell 通常是 Bash,但其他 shell 派生的解决方案(如 Perl 或 Python(也被接受。
一个简单的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
掩码,使用字母"A"到"F"表示大于 9 和两位数字的十六进制数字带0
填充的宽度OFS="
:设置 O输出 FS 以匹配 FS
$2
赋值始终为 true,并且没有给出其他操作,awk
始终将结果显示为默认操作。
您可以使用 perl - 当使用带有 e
标志的替换运算符时,您可以传递一个函数来处理替换值:
echo abc | perl -ne 's/(.+)/uc($1);print/e' # ABC
然后,您可以使用sprintf
函数通过%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-"