bash Shell脚本将文件中的十六进制值转换为十进制

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22958920/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 10:09:37  来源:igfitidea点击:

Shell Script to convert hexadecimal values in a file to decimal

bashshellsyntax-errorbc

提问by user3514650

I have a file named as textcontaining all hexadecimal numbers. I wrote the following code to convert those values to decimal:

我有一个名为 as 的文件,text其中包含所有十六进制数字。我编写了以下代码将这些值转换为十进制:

for line in `cat text`; do

arp=$(echo "ibase=16; $line" | bc);echo $arp
     done

But it's giving me the following error:

但它给了我以下错误:

(standard_in) 1: syntax error

My input file contains one column of hexadecimal values, e.g.

我的输入文件包含一列十六进制值,例如

428a2f98 
71374491 
b5c0fbcf

回答by Ashkan

If your hex numbers are in the following form:

如果您的十六进制数字采用以下形式:

0x1
0x2
0x3
0x4
0x5
0x6
0x7
0x8
0x9
0xA
0xB
0xC
0xD
0xE
0xF

I mean prefixed with 0xyou can use:

我的意思是0x你可以使用前缀:

while read line
do
     printf '%d\n' $line

done < text

Ouput:

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

回答by Adrian Frühwirth

It's not bashthat produces the error, it's bcwhich requires hexadecimal numbers to use uppercase letters while your input file uses lowercase letters.

这不是bash产生错误,而是bc需要十六进制数字才能使用大写字母,而您的输入文件使用小写字母。

If you use bash 4you can use ${foo^^}to expand $footo uppercase:

如果你使用bash 4你可以使用${foo^^}扩展$foo为大写:

bc <<< "ibase=16; ${line^^}"

or you can use tr:

或者你可以使用tr

bc <<< "ibase=16; $(tr '[:lower:]' '[:upper:]' <<< "${line}")"

回答by albfan

Although this question is answered, when you don't know exactly the position of numbers, this sed oneliner can help other people looking for help, and only finding this question on the net:

虽然回答了这个问题,但是当你不知道数字的确切位置时,这个sed oneliner可以帮助其他人寻求帮助,并且只能在网上找到这个问题:

$ cat file | sed 's/^/echo "/;s/(0x\(..\))/($(echo "ibase=16;\U\E"\|bc))/g;s/$/"/e'

Explaining:

解释:

  • s/^/echo "/adds echo "at start
  • s/(0x\(..\))/(\$(echo "ibase=16;\U\1\E"\|bc))/gneeds further explaining:
    1. find (0x..)pattern. You can change to ^........in your case
    2. creates a subshell $()where hex pattern \1is procesed by bc
      • \Uis used to uppercase hex digits. \Estops uppercasing.
  • s/$/"/eadds "at end and process line with sh
  • s/^/echo "/echo "在开始时添加
  • s/(0x\(..\))/(\$(echo "ibase=16;\U\1\E"\|bc))/g需要进一步说明:
    1. 找到(0x..)模式。您可以根据^........您的情况更改为
    2. 创建一个由bc 处理$()十六进制模式的子\1外壳
      • \U用于大写十六进制数字。\E停止大写。
  • s/$/"/e"使用 sh 在末尾添加和处理线

You can test it on xmodmapoutput, which output hexadecimal characters for modifiers, while xevshows modifiers as decimals.

您可以在xmodmap输出上测试它,它输出修饰符的十六进制字符,而xev 将修饰符显示为小数。

Hope it becomes handy in other use cases

希望它在其他用例中变得方便

回答by user3514650

while read line
do
    arp=$(echo "ibase=16; $line" | bc)
    echo $arp
done < in.txt

For in.txt

为了 in.txt

1
2
3
4
5
6
7
8
9
A
B
C
D
E
F
A0
A1
FF

This prints:

这打印:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
160
161
255