0

I want to get the variables $color and $number from a string that in general is like this: "something, numColor (number)". The color might be W, U, B, R, G. If there is no color the variable color should be C if the string before the comma doesn't have the word land or L otherwise. If there is more than one color the variable $color should be M. Here are some examples of what the string may look like and what the variables should be:

  • Sorcery, R (1) $color=R, $number=1
  • Creature — Beast 5/3, 4G (5) $color=G $number=5
  • Sorcery, 1WWU (4) $color=M $number=4
  • Legendary Land $color=L $number=0
  • Artifact, 0 $color=C $number=0
  • Legendary Creature — Eldrazi 15/15, 15 (15) $color=C $number=15
  • What language are you talking about? – Lucas Dec 26 '14 at 23:16
1

You can do task by sed on-liner:

sed '/(\?\([0-9]\+\))\?$/s//; number=\1/
     t n
     s/$/; number=0/
     :n
     /^.*, [0-9]\?\([WURBG]\)/{
                               s//color=\1/
                               s/[WURBG]\{2,\}/M/
                              }
     /[Ll]and/s/^[^;]*/color=L /
     /color/!s/^[^;]*/color=C /' file

But I'd like to offer put commands in script file:

#!/bin/sed -f
/(\?\([0-9]\+\))\?$/s//; number=\1/
t n
s/$/; number=0/
:n
/^.*, [0-9]\?\([WURBG]\)/{
    s//color=\1/
    s/[WURBG]\{2,\}/M/
}
/[Ll]and/s/^[^;]*/color=L /
/color/!s/^[^;]*/color=C /

then do

sed -f script.file file

Please note that all above regex are tested on your example only and if you meet unproper works its can be settled by a little tune up.

  • It works perfectly. – Arturo Dec 27 '14 at 16:19
0

While you can do this sort of thing by wrapping the more primitive Unix tools — grep, sed, awk, etc. — in a shell script, this sort of problem really wants to be handled in a full programming language that has a powerful regular expression system. Personally, I'd reach for Perl:

#!/usr/bin/perl -w
use strict;

my $line = 0;
my ($junk, $color, $number);

open my $data, '<', 'data.txt' or die "open: $!\n";
while (<$data>) {
    chomp;
    ++$line;

    if (m/Land/) {
        print "color=L, number=0\n";
    }
    else {
        ($junk, $color, $number) = m/, (\d+)?([WURBG]+) \((\d+)\)$/;
        if (defined $color and defined $number) {
            $color = 'M' if length($color) > 1;
            print "color=$color, number=$number\n";
        }
        else {
            ($junk, $number) = m/, (\d+)? ?\((\d+)\)$/;
            if (defined $number) {
                print "color=C, number=$number\n";
            }
            else {
                print "Line #$line is malformed!\n";
            }
        }
    }
}

data.txt contains this:

Sorcery, R (1)
Creature — Beast 5/3, 4G (5)
Sorcery, 1WWU (4)
Legendary Land
Artifact, (0)
Legendary Creature — Eldrazi 15/15, 15 (15)

There's just one difference from what you posted: the "Artifact" line in your question doesn't have parentheses around the 0 value, which would require an exception to be made in the parser. This can be added, but I don't see why that's better than fixing the format of the data file.

I assume you don't simply want the color and number values printed out, as this script does. You would put your own code in for each of the print lines.

The $junk bit comes from my assumption that the digit before the color letter(s) might be significant. I'm using it to help the parser do its thing. If you have a real use for this digit, you can rename the $junk variable to have semantic meaning. It's only "junk" to me, because I don't know what the value means.


  • I don't know perl works. How can I use this function in my program? unix.stackexchange.com/questions/176088/… – Arturo Dec 27 '14 at 0:18
  • The fact that you don't know how Perl works doesn't affect the correctness of the answer. You didn't specify which tools must be used to solve the problem. All that should concern you is whether the problem you posed above is in fact solved. You test that by copying the Perl script as given to a file on your system, running chmod +x on it to make it run, saving data.txt to a file in the same directory, running the script, and inspecting the output. You will find that the problem you posed above is solved, so you should therefore accept my answer. – Warren Young Dec 27 '14 at 0:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.