将文本文件中的十六进制值替换为(修改后的)十进制值

将文本文件中的十六进制值替换为(修改后的)十进制值

在文件内test.txt我有一个十六进制值

0x0000000000000000000000000000000000000000047546124890225541102135415377465907

只有一行。没有其他线条或字符。它也仅由 0x 标识。

我想将这个十六进制值转换为十进制(388355321549592156970965297418600041568519),减去 1,并用此操作的结果覆盖原始值test.txt

最终,文件中的数据test.txt应该从

0x0000000000000000000000000000000000000000047546124890225541102135415377465907

388355321549592156970965297418600041568518

如果您能告诉我如何使用 Bash(Linux shell)执行此操作,我将不胜感激。

答案1

使用perl,就地编辑文件:

perl -Mbigint -lpi -e '$_ = hex($_) - 1' your-file

假设整行都是十六进制数字。要转换所有十六进制数字,无论它们位于何处:

perl -Mbigint -lpi -e 's{\b0x[\da-f]+\b}{hex($&) - 1}gie' your-file

答案2

GNUawk

gawk -M '{print strtonum($0)-1}' file

-M(或--bignum) 用于任意精度算术。strtonum($0)获取记录的数值,将字符串视为十六进制数字,因为它以 开头0x。用于-i inplace输入文件的就地编辑。

答案3

通过 bash 中的一个命令,使用这里的字符串和计算器(带有后缀表示法):

dc -e '16iAo?1-p' <<<$(<file) >file

16i-输入基数
Ao-输出基数
?-读取一行
1--减一
p-印刷

注意:您的示例中未指定。dc计算器接受大写的十六进制数字 [ABCDEF]。

答案4

当问题询问文件中某处的十六进制数字时给出了这个答案。后来,问题被更新为整个文件仅由该数字组成。这个答案仍然有效,但当然你不会sed在这种特殊情况下使用。我仍然把它留在这里,作为寻求原始问题答案的人的参考。还请注意评论。

如果您有bash,您可能也有 GNU sed(带有命令e标志s)。然后你还需要bc计算器,因为你的数字太大了bash

sed 's/^0x0*\(.*\)/echo "ibase=16; \1-1"|bc/e' yourfile
  • 我认为,以 开头的每一行都0x应该被转换,但是您可以轻松地调整它
  • 0x0*\(.*\)是要改变的模式。我们删除了前导0x和多余的前导零,而其他所有内容都在 中,因此可以在替换中\(…\)引用\1
  • echo "ibase=16; \1-1"|bce是替换后shell要执行的shell命令
  • 实际计算是\1-1,即清理后的十六进制数减一。告诉这是一个十六进制ibase=16数字bc

相关内容