13

我正在尝试解析一些由 Javas 编写的数据的脚本DataOutputStream#writeLong(...)。由于 java 似乎总是写大端,我在将字节馈送到od. 这是因为od总是假设字节序与您当前所在的拱的字节序相匹配,而我在一个小字节序机器上。

我正在寻找一种简单的单线来反转字节顺序。假设您知道文件的最后 8 个字节是通过上述writeLong(...)方法写入的长字节。我目前打印这么长的最佳尝试是

tail -c 8 file | tac | od -t d8

,但tac似乎只适用于文本(很公平)。我发现了一些对 的引用dd conv=swab,但这只会成对交换字节,并且不能反转这八个字节。

有谁知道一个好的单线?

4

6 回答 6

13

您可以使用 objcopy:

$ objcopy -I binary -O binary --reverse-bytes=num inputfile.bin outputfile.bin

其中 num 为 2 或 4。

于 2013-10-10T06:05:49.803 回答
9

最后求助于Perl。使用了我在PERL One Liners找到的单衬里:

tail -c 8 file | perl -0777e 'print scalar reverse <>' | od -t d8

分隔符对0777我来说有点令人费解,但是debian admin 的这个页面似乎暗示它是“无记录分隔符”的占位符,触发了一个完整的反向字节每个字节。

欢迎提出其他建议。

编辑:在对 tac.c 的评论中找到另一个命令,我从 GNU coreutils 下载了该命令:

将每个 FILE 或标准输入(如果没有给出或遇到 FILE 名称“-”)复制到标准输出,记录的顺序颠倒。记录由字符串的实例分隔,如果没有给出则用换行符分隔。默认情况下,分隔符字符串附加到文件中记录的末尾。

选项:-b、--before 分隔符附加到文件中它之前的记录的开头。-r, --regex 分隔符是正则表达式。-s, --separator=separator 使用 SEPARATOR 作为记录分隔符。

要逐字节反转文件,请使用(在 bash、ksh 或 sh 中): tac -r -s '.\| ' 文件

于 2011-06-22T14:02:31.987 回答
5

使用dd,卢克!

dd if=sourcefile of=resultfile conv=swab
于 2015-07-28T17:15:53.257 回答
3

Note the next version of GNU coreutils (>= 8.23) will add the --endian={little,big} option to the od command

于 2014-02-08T19:46:13.197 回答
2

我想出了这个 Perl one-liner 来将 4 字节整数从一个字节序转换为另一个字节序:

$ perl -e 'open F,shift; do { read(F,$a,4); print scalar reverse($a);} while(!eof(F));' bigend.bin > littlend.bin

这可能在真正的 Linux 机器上运行良好,但 Cygwin 最后咬了我一口,将二进制文件视为文本并在每个 0x0A 字节(又名换行符)之前插入一个 0x0D(又名 CR)。但是,如果您通过管道传输到cat -,它似乎不会理会它。这对我有用:

$ perl -e 'open F,shift; do { read(F,$a,4); print scalar reverse($a);} while(!eof(F));' bigend.bin | cat - > littlend.bin
于 2013-03-08T18:52:19.997 回答
1

重击:

od -b -v -w8 | while read pfx b8 ; do [ "$b8" ] && echo -n 12345678 | tr 87654321 \\${b8// /\\} ; done

为了根据 的输出样式更加健壮od,它可能需要压缩空格(在"| sed 's/ */ /g'"之后插入w8)。

于 2014-07-09T15:09:42.417 回答