编辑 #1 的答案

编辑 #1 的答案

我需要将文本文件中的十进制值列表转换为十六进制格式,例如 test.txt 可能包含:

131072
196608
262144
327680
393216
...

输出应该是十六进制值列表(十六进制 8 位数字,带前导零):

00020000
00030000
00040000
...

输出被打印到文本文件中。如何使用 python 或 linux shell 脚本来实现这个?

编辑#1

我错过了一个额外的操作:我需要将80000000十六进制添加到每个创建的十六进制值中。 (算术加法,应用于已创建的十六进制值列表)。

答案1

您可以使用printf和 来执行此操作bash

printf '%08x\n' $(< test.txt)

或者使用 printf 和 bc...只是...因为?

printf '%08s\n' $(bc <<<"obase=16; $(< test.txt)")

为了将输出打印到文本文件,只需使用 shell 重定向,>例如:

printf '%08x\n' $(< test.txt) > output.txt

答案2

使用awk

$ awk '/[0-9]/ { printf("%08x\n", $0) }' file
00020000
00030000
00040000
00050000
00060000

答案3

三种可能的解决方案(假设每行都是一组仅有的数字):

对于 ksh、bash、zsh 等 shell:

printf '%08x\n' $(<infile)

仅适用于 bash

<file.txt mapfile -t arr;   printf '%08x\n' "${arr[@]}" 

对于更简单的 shell:dash(基于 Debian 的系统中的默认 sh)、ash(busybox 模拟 shell)、yash 以及 AIX 和 Solaris 中的一些默认 shell:

printf '%08x\n' $(cat infile)

事实上,对于像 Heirloom 版本(类似 Bourne)这样的 shell,它需要这样写(它确实适用于上面列出的所有 posix shell,但我强烈建议不要使用它):

$ printf '%08x\n' `cat infile`

编辑 #1 的答案

了解十六进制值80000000将导致 32 位计算机溢出(目前不常见,但有可能)。检查echo "$((0x80000000))"不要打印负值。

$ for i in $(<infile); do printf '%08x\n' "$(($i+0x80000000))"; done
80020000
80030000
80040000
80050000
80060000

答案4

使用朱莉娅

$ julia -e 'function hexadd(x) hex(( x + 0x80000000),8) end ; output = open("output.txt","w") ; open("test.txt") do inputfile for num in eachline(inputfile) write(output,"$(hexadd(parse(Int,num)))\n") end end'

阅读多行应该更容易:

function hexadd(x)
    hex(( x + 0x80000000),8)
end
output = open("output.txt","w")
open("test.txt") do inputfile
    for num in eachline(inputfile)
        write(output,"$(hexadd(parse(Int,num)))\n")
    end
end
  • hex( value, pad)将值转换为十六进制,并根据需要添加填充。
    hexadd需要整数作为输入,因此我们将字符串( 的输出eachline)转换为Intwithparse(Int,"string")并在我们的函数中使用它。
  • julia -e计算一个表达式。
  • julia可以原生安装在fedora、ubuntu上

使用直流电:

$ dc -f test.txt -e '16o16i[80000000+psaz1<r]dsrx80000000+p' > output.txt

解释:

  • dc -f test.txt -e '16o 16i [80000000 + p sa z 1 <r] sr z 1 <r 80000000 + p' > output.txt
  • -f file将文件内容压入堆栈
  • -e执行表达式
  • 16o将输出转换为基数 16
  • 16i假设输入以 16 为基数。这种情况发生在读取文件后,因此文件是以 10 为基数读取的。更明确地说,我可以这样做dc -e '10i' -f file -e '16 i 8000000'
  • [...]将字符串压入堆栈。该字符串将用作宏。
  • 80000000 +将当前堆栈顶部与十六进制 80000000 相加。将结果推入堆栈顶部。
  • p打印当前堆栈顶部,而不弹出。唯一打印换行符的打印选项。
  • sa弹出堆栈顶部并将其存储在寄存器“a”中。它永远不会被使用,只是摆脱麻袋顶部的一种方法。
  • z当前堆栈顶部现在具有堆栈深度。需要结束递归调用。
  • 1将 1 推入堆栈顶部。与之前推送的堆栈深度 (z) 相比很有用。
  • <r比较堆栈中的 2 个值,如果第 2 个值小于第一个值,则执行寄存器“r”。实际上比较堆栈深度和“1”。
  • sr弹出并存储在寄存器“r”中。现在宏位于寄存器“r”中,只要堆栈深度大于 1,就会执行。除了还没有任何东西调用它。
  • d复制栈顶并压入。
  • x作为宏执行堆栈顶部。
  • d sr x复制宏并推送,现在堆栈有 2 个副本,弹出并存储顶部副本以注册,弹出并执行第二个副本...
  • 因此,推送堆栈深度和 1,比较并执行,对于最后一个元素,再次添加十六进制值并打印。

相关内容