pryrt has asked for the wisdom of the Perl Monks concerning the following question:
how do you set binmode for the input and output of a perl -pi script.pl *.file in-place edit? I had hoped by doing binmode ${^LAST_FH}; binmode STDOUT;, that would cover it...
pi.pl:
use warnings; use strict; use Data::Dumper; my ($d0, $count); BEGIN { $Data::Dumper::Terse=$Data::Dumper::Useqq=1; $Data::Dumper::Indent=0; $/=qq(\0); $main::total = 0; $main::l = 0; binmode STDIN; binmode STDOUT; }; binmode ${^LAST_FH}; $d0 = Dumper($_); $main::total += $count = s/w/v/g || 0; $main::l+=length($_); printf STDERR qq(%-32s vs %-32s: cnt=%d tot=%d l=%d\n), $d0, Dumper($_ +), $count, $main::total, $main::l;
windows cmd.exe:
@set PROMPT=$G rem create binary file perl -e "binmode STDOUT; $,=qq(\0); print qq(bin\n), qw(encoded file), + qq(r:\r\0n:\n\0nr:\n\r\0rn:\r\n), qw(with EOL-like sequences)" > src +.bin rem process perl -pi.orig pi.pl src.bin rem show the file sizes are different dir src.bin* rem use xxd.exe from gvim for windows to show hexdump xxd src.bin.orig xxd src.bin @set PROMPT=$P$G
output:
>rem create binary file >perl -e "binmode STDOUT; $,=qq(\0); print qq(bin\n), qw(encoded file) +, qq(r:\r\0n:\n\0nr:\n\r\0rn:\r\n), qw(with EOL-like sequences)" > sr +c.bin >rem process >perl -pi.orig pi.pl src.bin "bin\n\0" vs "bin\n\0" : +cnt=0 tot=0 l=5 "encoded\0" vs "encoded\0" : +cnt=0 tot=0 l=13 "file\0" vs "file\0" : +cnt=0 tot=0 l=18 "r:\r\0" vs "r:\r\0" : +cnt=0 tot=0 l=22 "n:\n\0" vs "n:\n\0" : +cnt=0 tot=0 l=26 "nr:\n\r\0" vs "nr:\n\r\0" : +cnt=0 tot=0 l=32 "rn:\r\n\0" vs "rn:\r\n\0" : +cnt=0 tot=0 l=38 "with\0" vs "vith\0" : +cnt=1 tot=1 l=43 "EOL-like\0" vs "EOL-like\0" : +cnt=0 tot=1 l=52 "sequences" vs "sequences" : +cnt=0 tot=1 l=61 >rem show the file sizes are different >dir src.bin* Volume in drive C is System Volume Serial Number is 309C-2FED Directory of C:\Users\peter.jones\Documents\HX27\LocalDatalogs\Gage\P +ASS2 12/07/2016 03:11 PM 65 src.bin 12/07/2016 03:11 PM 61 src.bin.orig 2 File(s) 126 bytes 0 Dir(s) 82,748,403,712 bytes free >rem use xxd.exe from gvim for windows to show hexdump >xxd src.bin.orig 0000000: 6269 6e0a 0065 6e63 6f64 6564 0066 696c bin..encoded.fil 0000010: 6500 723a 0d00 6e3a 0a00 6e72 3a0a 0d00 e.r:..n:..nr:... 0000020: 726e 3a0d 0a00 7769 7468 0045 4f4c 2d6c rn:...with.EOL-l 0000030: 696b 6500 7365 7175 656e 6365 73 ike.sequences >xxd src.bin 0000000: 6269 6e0d 0a00 656e 636f 6465 6400 6669 bin...encoded.fi 0000010: 6c65 0072 3a0d 006e 3a0d 0a00 6e72 3a0d le.r:..n:...nr:. 0000020: 0a0d 0072 6e3a 0d0d 0a00 7669 7468 0045 ...rn:....vith.E 0000030: 4f4c 2d6c 696b 6500 7365 7175 656e 6365 OL-like.sequence 0000040: 73 s
I've gotten the input as close to binmode as I can, in that for the sample input above, the sum of the lengths of $_ totals 61, which matches that example input. But putting binmode STDOUT in either the BEGIN, the main, or both, does not seem to help the output file be the same length. I tried perl -C0 -pi... (from perlrun), hoping to make it all :raw equivalent, but with no change. I looked thru perlvar to try to find an output-equivalent of ${^LAST_FH}, but didn't see anything.
In the end, I'll probably just stop trying the magic perl -pi and make a manual in-place loop, where I open the ARGV input and output handles myself, so I have full control. But after this much investigation, I'd really like to find out if it's possible to make the whole in-place pipeline binmode.
ps: No, converting 'w' to 'v' is not my end goal :-). I just used that as a SCCE to show the basic problem binmode issue: I want to be able to do all my working (where my actual manipulations will preserve byte-length) without changing the EOL-like characters for this binary file.
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: binmode i/o for perl -pi in-place editing
by choroba (Cardinal) on Dec 07, 2016 at 23:40 UTC | |
by pryrt (Abbot) on Dec 08, 2016 at 03:46 UTC | |
by pryrt (Abbot) on Dec 08, 2016 at 16:20 UTC | |
by shmem (Chancellor) on Dec 08, 2016 at 22:48 UTC | |
by pryrt (Abbot) on Dec 09, 2016 at 14:44 UTC | |
Re: binmode i/o for perl -pi in-place editing
by Marshall (Canon) on Dec 09, 2016 at 00:16 UTC | |
by pryrt (Abbot) on Dec 09, 2016 at 15:17 UTC | |
by shmem (Chancellor) on Dec 09, 2016 at 16:38 UTC |