用于反转字节顺序/更改字节顺序的命令行
我在一些脚本中尝试解析由 Java DataOutputStream#writeLong(...)
编写的一些数据。由于java似乎总是写大端,所以我在向od
提供字节时遇到问题。这是因为 od
始终假设字节序与您当前所在的架构的字节序相匹配,而我使用的是小型字节序机器。
我正在寻找一种简单的单行来反转字节顺序。假设您知道文件的最后 8 个字节是由上述 writeLong(...)
方法写入的 long。我目前打印这么长的最佳尝试是
tail -c 8 file | tac | od -t d8
,但 tac 似乎只适用于文本(很公平)。我发现了一些对 dd conv=swab 的引用,但这只能成对交换字节,并且不能反转这八个字节。
有谁知道这方面的好单行本吗?
I'm hacking around in some scripts trying to parse some data written by Javas DataOutputStream#writeLong(...)
. Since java always seems to write big endian, I have a problem feeding the bytes to od
. This is due to the fact that od
always assumes that the endianess matches the endianess of the arch that you are currently on, and I'm on a little endian machine.
I'm looking for an easy one-liner to reverse the byte order. Let's say that you know that the last 8 bytes of a file is a long written by the aforementioned writeLong(...)
method. My current best attempt to print this long is
tail -c 8 file | tac | od -t d8
, but tac
only seems to work on text (fair enough). I've found some references to dd conv=swab
, but this only swaps bytes in pairs, and cannot reverse these eight bytes.
Does anyone know a good one-liner for this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
您可以使用 objcopy:
其中 num 是 2 或 4。
You could use objcopy:
where num is either 2 or 4.
用过dd,卢克!
Used dd, Luke!
最后求助于Perl。使用了我在 PERL One Liners 中找到的单行代码:
0777
分隔符让我有点困惑,但是 debian admin 的 this 页面似乎表明它是“no”的占位符记录分隔符,触发每个字节的完全反向字节。欢迎其他建议。
编辑:在 tac.c 的评论中找到另一个命令,我从 GNU coreutils 下载了该命令:
Resorted to Perl in the end. Used a one-liner which I found at PERL One Liners:
The
0777
separator char was a bit puzzling to me, but this page at debian admin seems to suggest that it is a placeholder for 'no record separator', triggering a complete reverse byte-per byte.Other suggestions are welcome.
EDIT: Found another command in a comment to tac.c, which I downloaded from GNU coreutils:
请注意,下一版本的 GNU coreutils (>= 8.23) 将在 od 命令中添加 --endian={little,big} 选项
Note the next version of GNU coreutils (>= 8.23) will add the --endian={little,big} option to the od command
我想出了这个 Perl 单行代码将 4 字节整数从一种字节序转换为另一种字节序:
这可能在真正的 Linux 机器上工作得很好,但 Cygwin 最后咬了我,将二进制文件视为文本并插入 0x0D(又名CR)在每个 0x0A 字节(又名换行符)之前。但如果你通过管道传输到
cat -
,似乎就不管它了。这对我有用:I came up with this Perl one-liner to convert 4-byte integers from one endianness to another:
That probably works fine on real Linux machines, but Cygwin bit me in the end, treating the binary file as text and inserting a 0x0D (aka CR) before each 0x0A byte (aka newline). But if you pipe to
cat -
, it seems to leave it alone. This works for me:BASH:
为了根据
od
的输出样式变得更加健壮,它可能需要压缩空格(插入"| sed 's/ */ /g'"
在w8
之后)。BASH:
To be a bit more robust depending on the output style of
od
, it may need to compress spaces ( insert"| sed 's/ */ /g'"
after thew8
).xxd
有两个标志-e
和-g
以满足您的目的。这样,您可以执行以下操作:
xxd
has two flags-e
and-g
for your purpose.This way, you can do:
一种简单的 Python 方法,每 4 个字节反转一次。使用较新的 Python 3.8+ walrus 运算符:
上面的内容很容易理解,但如果您想要更紧凑的 oneliner,您可以将上面的脚本修改为:
import sys\nwhile word := sys.stdin.buffer.read(4):\n sys.stdout.buffer.write(bytes(reversed(word)))'注意
$''
表示法假设您正在使用重击。它允许您在 Python 命令中使用换行符。例如,在标准输入上交换一些字符:
A simple Python approach that reverses every 4 bytes. Uses newer Python 3.8+ walrus operator:
The above is simple to understand, but if you want a more compact oneliner, you can modify the above script into:
import sys\nwhile word := sys.stdin.buffer.read(4):\n sys.stdout.buffer.write(bytes(reversed(word)))'Note the
$''
notation assumes you're using bash. It allows you to use newlines in the Python command.As an example, swapping some chars on stdin:
我发现这个命令对于交换 4 字节字节顺序效果很好
I found that this command worked well for swapping 4 bytes for endianness