tags:

views:

387

answers:

3

Hello friends,

I'm looking for a way to take the TEXT characters from a 4byte BINARY file to array or TEXT file,

Lets say my input file is:

00000000  2e 00 00 00 01 00 00 00  02 00 00 00 03 00 00 00  |................|
00000010  04 00 00 00 05 00 00 00  06 00 00 00 07 00 00 00  |................|
00000020  08 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000070  00 00 00 00 00 00 00 00                           |........|
00000078

And my desired output is:

46,1,2,3,4,5,6,7,8,9,0,0...

The output can be a TEXT file or an array.

I notice that the pack/unpack functions may help here, but I couldn't figure how to use them properly,

if anybody can give me an appropriate example I'll appreciate that.

Thanks for any comment, Yohad.

+7  A: 

Use unpack:

local $/;
@_=unpack("V*", <>);

gets you an array. So as an inefficient (don't try on huge files) example:

perl -e 'local$/;print join(",",map{sprintf("%d",$_)}unpack("V*",<>))' thebinaryfile
p00ya
YoDar
It probably should be mentioned that the 'V' template interprets the input bytes precisely as 32-bit little-endian 'long' numbers. Depending on exactly what you're doing, 'L' might be more appropriate -- see 'perldoc -f pack' for the gory details, though.
dlowe
+1  A: 

The answer is dependent on what you consider an ASCII character. Anything below 128 is technically an ASCII character, but I am assuming you mean characters you normally find in a text file. In that case, try this:

#!/usr/bin/perl

use strict;
use warnings;
use bytes;

$/ = \1024; #read 1k at a time
while (<>) {
    for my $char (split //) {
     my $ord = ord $char;
     if ($char > 31 and $char < 127 or $char =~ /\r\n\t/) {
      print "$ord,"
     }
    }
}
Chas. Owens
A: 

od -t d4 -v

Larry