问题
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 with0
paddingOFS=\"
: 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