如何用Perl将指定格式的数据写入二进制文件?

发布于 2024-09-15 02:09:41 字数 639 浏览 7 评论 0原文

这可能是一个相当新手的问题,但我需要处理某个文本文件并将其内容转储到二进制文件中,我不知道如何 - 我决定使用 perl,但我的 perl 技能相当低。我可能应该用 C++ 编写这个,但这对于 perl 来说似乎是一个很好且简单的任务,所以为什么不学习一些新的东西呢? ;) 该文本文件有数千行,格式如下:

2A02FC42 4

您可以将其视为十六进制数字(长度始终 8)和常规数字。现在我需要将所有行转储到以下格式的二进制文件中(使用十六进制编辑器查看时应该如下所示):

42FC022A00000004

更多示例,以便清楚:

70726F67 36< /代码> -> 676F727000000024
6A656374 471 -> 7463656A000001D7

解析输入文件的部分很简单,但我陷入了第二部分,我应该将其写入二进制文件。我不知道如何以这种方式格式化数据,甚至不知道如何以二进制模式输出内容。有人可以帮我吗?

谢谢。

编辑:更新了示例,忘记了字节序 - 我在 LE 系统上。

this might be quite a newbie question, but i need to process a certain text file and dump its content into a binary file and i do not know how - i decided to use perl, but my perl skills are quite low. I probably should have written this in C++, but this seem like a nice and easy task for perl, so why not learn something new? ;) The text file has thousands of lines in this format:

2A02FC42 4

You can look at it as a hexadecimal number (the length is ALWAYS 8) and a regular number. Now i need to dump all the lines into a binary file in this format (it should look like this when viewed with a hex editor):

42FC022A00000004

More examples so it is clear:

70726F67 36 -> 676F727000000024
6A656374 471 -> 7463656A000001D7

The part of parsing the input file is easy, but i'm stuck on the second part, where i should write this into a binary file. I have no idea how to format the data in this way or even how to output things in binary mode. Can someone help me out here?

Thanks.

EDIT: updated the examples, forgot about endiannes - im on a LE system.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

脱离于你 2024-09-22 02:09:41

使用 pack

#! /usr/bin/perl

use warnings;
use strict;

# demo only    
*ARGV = *DATA;

while (<>) {
  my($a,$b) = split;
  $a = join "", reverse $a =~ /(..)/g;
  $b = sprintf "%08x", $b;

  print pack "H*" => $a . $b;
}

__DATA__
2A02FC42 4
70726F67 36
6A656374 471

示例运行:

$ ./prog.pl | od -t x1
0000000 42 fc 02 2a 00 00 00 04 67 6f 72 70 00 00 00 24
0000020 74 63 65 6a 00 00 01 d7
0000030

Use pack:

#! /usr/bin/perl

use warnings;
use strict;

# demo only    
*ARGV = *DATA;

while (<>) {
  my($a,$b) = split;
  $a = join "", reverse $a =~ /(..)/g;
  $b = sprintf "%08x", $b;

  print pack "H*" => $a . $b;
}

__DATA__
2A02FC42 4
70726F67 36
6A656374 471

Sample run:

$ ./prog.pl | od -t x1
0000000 42 fc 02 2a 00 00 00 04 67 6f 72 70 00 00 00 24
0000020 74 63 65 6a 00 00 01 d7
0000030
伤感在游骋 2024-09-22 02:09:41

我的版本(已测试):

my $fout;
if ( ! open( $fout, ">/tmp/deleteme.bin" ) ) {
    die( "Failed to open /tmp/deleteme.bin: $!" );
}
binmode( $fout );

while ( <DATA> ) {
    my ( $left, $right ) = split( /\s+/s, $_ );

    my $output = pack( "VN", hex($left), int($right) );
    printf(
        STDERR
        "  note, %8X %d -> " . ( "%02X" x 8 ) . "\n",
        hex($left), $right,
        map { $_ } unpack( "C8", $output )
    );

    print( $fout $output );
}
close( $fout );

__DATA__
70726F67 36 -> 676F727000000024
6A656374 471 -> 7463656A000001D7

输出:

note, 70726F67 36 -> 676F727000000024
note, 6A656374 471 -> 7463656A000001D7

My version (tested):

my $fout;
if ( ! open( $fout, ">/tmp/deleteme.bin" ) ) {
    die( "Failed to open /tmp/deleteme.bin: $!" );
}
binmode( $fout );

while ( <DATA> ) {
    my ( $left, $right ) = split( /\s+/s, $_ );

    my $output = pack( "VN", hex($left), int($right) );
    printf(
        STDERR
        "  note, %8X %d -> " . ( "%02X" x 8 ) . "\n",
        hex($left), $right,
        map { $_ } unpack( "C8", $output )
    );

    print( $fout $output );
}
close( $fout );

__DATA__
70726F67 36 -> 676F727000000024
6A656374 471 -> 7463656A000001D7

outputs:

note, 70726F67 36 -> 676F727000000024
note, 6A656374 471 -> 7463656A000001D7
带刺的爱情 2024-09-22 02:09:41

规范的方法是使用 pack。假设您从文本文件中读取的数据已转换为数字(包括十六进制),并存储在变量 $x$y 中。那么你应该做类似的事情

 print OUTFILE pack("NN", $x, $y);

如果你需要不同的字节顺序,你将不得不使用
NN 不同的模板,请参阅 perldoc -f pack 了解详细信息。

The canonical way is to use pack. Let's suppose that the data you have read from the text file is already converted into numbers (including the hex one), and is stored in vars $x and $y. Then you should do something like

 print OUTFILE pack("NN", $x, $y);

If you require different byteorder, you will have to use
different template from NN, see perldoc -f pack for details.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文