How to write data in specified format into a binary file with Perl?
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 id开发者_开发知识库ea 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.
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
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
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.
精彩评论