2010/8/22 Uri Guttman <u...@stemsystems.com> > > >>>>> "AQ" == Albert Q <albert.q.p...@gmail.com> writes: > > a quick comment. pack is most likely not a beginner issue. i am sure you > will get help here but think about better forums for asking about > pack. there are plenty. pack is powerful and sometimes dark magic even > to experienced perl hackers (i know on very high level hacker who never > used pack/unpack.).
but I only have this mailing list, and I think it is not a heigh level problem :) > AQ> I have a text file containing hex strings such as: 12 34 56 78 90 ab cd > ef > AQ> now I want to change these hex strings to sequence of bytes with the > AQ> relative value of 0x12 0x34 0x56 .... > > AQ> sub proc_file > AQ> { > AQ> while(<$fin>) > AQ> { > AQ> my @values = split /\s+/; > AQ> print $fout join '' , map { pack 'H*', $_} @values; # method 1 > AQ> print $fout pack 'H*', join '', @values; # > method > AQ> 2 > AQ> print $fout pack 'H*', @values; # > method > AQ> 3 > AQ> } > AQ> } > > AQ> The result is that, both method 1 and method 2 works OK, but with method > 3, > AQ> I only get the first byte. For example, > AQ> if @values is 12 34 56 78 > AQ> pack 'H*', @values will get a string with only one byte 0x12 > AQ> from perlfun, I found that the pack function will gobble up that many > values > AQ> from the LIST except for some types, and 'H' is one of these types. > AQ> so, if I use > AQ> pack 'H*H*H*H*', @values; > AQ> I will get the correct result of 4 bytes 0x12 0x34 0x56 0x78 > > AQ> My question is, does there exist some other more simple way to accomplish > AQ> this transfrom, for example, just one modifier to tell the pack to use > all > AQ> items of the LIST? > > from the docs on pack: > > The "h" and "H" fields pack a string that many nybbles (4-bit > groups, representable as hexadecimal digits, 0-9a-f) long. > > If the input string of pack() is longer than needed, extra > characters are ignored. A "*" for the repeat count of pack() > means to use all the characters of the input field. On > unpack()ing the nybbles are converted to a string of hexadecimal > digits. > > the point is that H and h pack into and from a single string. hex is > usually in a string and the byte value is also a string. > > there is a newer feature (dunno which perl version got it first) which > is subtemplating (like grouping in a regex. the docs say this: > > A ()-group is a sub-TEMPLATE enclosed in parentheses. A group > may take a repeat count, both as postfix, and for unpack() also > via the "/" template character. Within each repetition of a > group, positioning with "@" starts again at 0. Therefore, the > result of > > pack( '@1A((@2A)@3A)', 'a', 'b', 'c' ) > is the string "\0a\0\0bc". > > so your solution is this: > > perl -le 'print unpack "H*", pack( "(H2)*", qw( 10 ab 9f ))' > 10ab9f > > as you can see it takes a list of hex and pack and unpacks it as > expected. > > uri > > -- > Uri Guttman ------ ...@stemsystems.com -------- http://www.sysarch.com -- > ----- Perl Code Review , Architecture, Development, Training, Support ------ > --------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com --------- Yes, it works well ! pack '(H*)*', @values will get the correct result. Thanks a lot ! -- missing the days we spend together -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/