http://www.perlmonks.org?node_id=1098323

randome has asked for the wisdom of the Perl Monks concerning the following question:

Hello, I have a huge file with over 700,00 entries with 18 columns. One column is in the format
--+-+ ---++ ????? -????
Now i have another list which corresponds to this code in a particular order
A-1 B-7 C-11 D-3 E-100
Now I need to match the expression above to the pattern, where +/- corresponds to A-E and ? corresponds to 0 and as an output I need to get a number. So the output should be
--+-+ = 122 (because 1+7+11+3+100) ---++= 122 ?????= 0 -???+= 101
This is just a sample, the numbers are much bigger and the pattern runs upto 24 times. Is there any way I can do it with perl scripting ? Thank you

Replies are listed 'Best First'.
Re: decoding pattern expression
by kennethk (Abbot) on Aug 22, 2014 at 14:25 UTC
    Is there any way I can do it with bash scripting ?
    If you want bash scripting, you've come to the wrong site. If you'd like some help doing this with Perl scripting, I'd probably use indices 0-4 instead of A-E, make an array (my @values = (1, 7, 11, 3, 100)) and then split your coded strings:
    my @terms = split //, $input; my $sum = 0; for my $i (0 .. @terms-1) { $sum += $values[$i] if $terms[$i] ne '?'; } print "$input = $sum\n";

    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

      Using substr might be slightly faster than split-ing to an array (YMMV):

      c:\@Work\Perl>perl -wMstrict -le "my @vectors = ( [ '--+-+', 122 ], [ '---++', 122 ], [ '?????', 0 ], [ '-????', 1 ], [ '-???-', 101 ], ); ;; my @map = (1, 7, 11, 3, 100); ;; use Test::More 'no_plan'; ;; for my $ar_vector (@vectors) { my ($s, $expected) = @$ar_vector; ;; my $cvt = convert($s); ok $cvt == $expected, qq{'$s' -> $expected (got $cvt)}; } ;; sub convert { my ($s) = @_; ;; my $sum = 0; $sum += substr($s, $_, 1) ne '?' ? $map[$_] : 0 for 0 .. length($s) +-1; return $sum; } " ok 1 - '--+-+' -> 122 (got 122) ok 2 - '---++' -> 122 (got 122) ok 3 - '?????' -> 0 (got 0) ok 4 - '-????' -> 1 (got 1) ok 5 - '-???-' -> 101 (got 101) 1..5

Re: decoding pattern expression
by Anonymous Monk on Aug 22, 2014 at 21:53 UTC

    This works for your sample data but probably not your real data:

    my $s = pack 'C5', qw[1 7 11 3 100]; say "$_: ", unpack '%C5', $s & tr/?+-/\0\xff/r for qw[ --+-+ ---++ ????? -???+ ];

    Output:

    --+-+: 122 ---++: 122 ?????: 0 -???+: 101
Re: decoding pattern expression
by GotToBTru (Prior) on Aug 22, 2014 at 14:28 UTC

    What have you tried so far?

    1 Peter 4:10
      i have tried a bit with bash scripting but didnt get too far

        That tells me nothing. I suppose I should have asked before that, do you have to use bash scripting? You probably can do it that way but it really isn't intended for that. And, this is a perl forum, not a bash scripting forum, so you may have to look elsewhere. OTOH, perl is the perfect tool for this problem. Interested in learning something? Check a perl tutorial like the ones on this site, and post what you come up with. We'll help.

        1 Peter 4:10
        FYI, that generally means:
        Show picturescode or it didn't happen.