Shell: In-file converting first field of a text file from decimal to hexadecimal

喜欢而已 提交于 2019-12-12 13:55:02

问题


This is my example text file:

$ cat RealVNC\ MRU.reg
"10"="Lamborghini-:1"
"16"="Terminus-"
"20"="Midnighter-:5915"
"35"="ThreepWood-:1"
"81"="Midnighter-:1"
"58"="Midnighter-"

And I would like to convert values of the first field (the numbers between "") from decimal to hexadecimal (it is a .reg file for Windows, so I meesed it up thinking the numbers were in a decimal base, and now the file is too long to manually edit).

Example result that I need to obtain:

$ cat Hex\ RealVNC\ MRU.reg
"0A"="Lamborghini-:1"
"10"="Terminus-"
"14"="Midnighter-:5915"
"23"="ThreepWood-:1"
"51"="Midnighter-:1"
"3A"="Midnighter-"

As can be seen, only the numbers have changed. Resulting numbers must be two characters long (RegEdit considers them different).
Changes in the order of the lines don't bother here, but I think it would be more "clean" a solution that doesn't change it.

I don't expect any number (be it decimal or hex) will have more than 2 characters, but a solution that considers this possibility will be best (as it is a more generic solution).

I have tested so far:

$ cat RealVNC\ MRU.reg | awk -F \" '{print $2}'
10
16
20
35
81
58

But I don't know who to in-line make the changes from dec to hex.

My shell is usually Bash, but other shell-derivated solutions (like Perl or Python) are accepted too.


回答1:


A simple 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-"

Explanation

  • -F\" : sets field separator (FS) to "

  • $2=sprintf("%02X", $2) : $2 is assigned to it’s printed version ( sprintf) with a %02X mask in hexadecimal using the letters 'A' to 'F' for hex digits greater than 9 and a two digits width with 0 padding

  • OFS=\" : sets the Output FS to match FS

The $2 assignation is always true and no additional action is given , awk always displays the results as it's default action.




回答2:


You can use perl - when using the substitution operator with the e flag you can pass a function to handle the replace value:

echo abc | perl -ne 's/(.+)/uc($1);print/e' # ABC   

You can then use sprintf function to convert decimal to hex with the %X conversion:

%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-"

If you want leading zero on 0-F single values you can use the prefix format %02X:

%02X
 ^^L Conversion
 |L Result length
 L- Prefix char

And the result:

$ 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-"


来源:https://stackoverflow.com/questions/33336086/shell-in-file-converting-first-field-of-a-text-file-from-decimal-to-hexadecimal

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!