Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Re^2: Convert binary file to ascii

by richz (Beadle)
on Jun 22, 2007 at 19:13 UTC ( [id://622888]=note: print w/replies, xml ) Need Help??


in reply to Re: Convert binary file to ascii
in thread Convert binary file to ascii

I want to print a newline after every 8 values. Is there any better way of doing this with your method besides the following?

@converted_list = map{sprintf '0x%04x', $_} unpack ('v*', $line); foreach $sample (@converted_list) { print OUTFILE "$sample, "; $ctr += 1; if (($ctr % 8) == 0) { print OUTFILE "\n"; $ctr = 0; } }

Replies are listed 'Best First'.
Re^3: Convert binary file to ascii
by BrowserUk (Patriarch) on Jun 22, 2007 at 19:38 UTC

    Probably the easiest way would be to set $/ = \16 so that you read the file in 16 bytes chunks.

    Ie. $/ = \16; while( my $line = <INFILE> ) { willresult in $line containing 16 bytes each time, which will give you your 8 values per output line.

    Simplistically, that make the program something like:

    #! perl -lw use strict; ## Note the -l above which makes print add newlines. open IN, '<:raw:perlio', $ARGV[0] or die $!; open OUT, '>', 'junk.out' or die $!; $/ = \16; ## read 16 bytes at a time; print join ',', map{ sprintf '0x%04x', $_ } unpack 'v*', $_ while <IN> +; close OUT; close IN;

    If there was (still) some way to binmode *ARGV, it could be reduced to a one-liner:

    perl -nle"BEGIN{$/=\16}print join',',map{sprintf'0x%04x',$_}unpack'v*' +,$_" binfile >outfile

    but without binmode, that fails if the file contains a ^Z (control-Z; ascii 26) character.

    Or you can go the other way and 'PBP-up' the above.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re^3: Convert binary file to ascii
by ikegami (Patriarch) on Jun 22, 2007 at 19:30 UTC

    Well, the $ctr = 0 doesn't do anything useful, and the $ctr += 1 could be merged into the if conditional.

    my @converted_list = map { sprintf('0x%04x', $_) } unpack('v*', $line) +; my $ctr; foreach (@converted_list) { print OUTFILE "$_, "; print OUTFILE "\n" unless ++$ctr % 8; }

    You could merge of all that together if you so desired, but that's probably a bit odd.

    my $ctr; print map { ++$ctr % 8 ? "$_, " : "$_\n" } map { sprintf('0x%04x', $_) } unpack('v*', $line);

    The simplest solution is probably to omit the counter altogether by only reading in 16 bytes at a time. As a bonus, it doesn't leave trailing comma when the file isn't an exact multiple of 16 bytes long.

    # Each line has 8 16-bit words, so 16 bytes. local $/ = \16; while (<INFILE>) { print join ', ', map { sprintf('0x%04x', $_) } unpack('v*', $_); print("\n"); }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://622888]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (5)
As of 2024-04-19 14:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found