Copiando duas palavras de uma string em duas variáveis

0

Eu quero pegar as variáveis $ color e $ number de uma string que em geral é assim: "something, numColor (number)". A cor pode ser W, U, B, R, G. Se não houver cor, a cor da variável deve ser C se a string antes da vírgula não tiver a palavra land ou L de outra forma. Se houver mais de uma cor, a variável $ color deve ser M. Aqui estão alguns exemplos de como a string pode parecer e quais devem ser as variáveis:

  • Feitiço, R (1) $color=R, $number=1
  • Criatura - Besta 5/3, 4G (5) $color=G $number=5
  • Feitiço, 1WWU (4) $color=M $number=4
  • Terra lendária $color=L $number=0
  • Artefato, 0 $color=C $number=0
  • Criatura Lendária - Eldrazi 15/15, 15 (15) $color=C $number=15
por Arturo 26.12.2014 / 23:43

2 respostas

1

Você pode realizar tarefas por sed on-liner:

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

Mas gostaria de oferecer comandos de colocação em script file :

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

faça

sed -f script.file file

Por favor, note que todos os regex acima são testados em seu exemplo apenas e se você encontrar trabalhos impróprios pode ser resolvido por um pouco de ajuste.

    
por 27.12.2014 / 01:13
0

Embora você possa fazer esse tipo de coisa envolvendo as ferramentas Unix mais primitivas - grep , sed , awk , etc. - em um script de shell, esse tipo de problema realmente deseja ser tratado linguagem de programação completa que possui um poderoso sistema de expressão regular. Pessoalmente, eu procuraria por 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 contém isto:

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

Há apenas uma diferença em relação ao que você postou: a linha "Artefato" em sua pergunta não tem parênteses em torno do valor 0, o que exigiria que uma exceção fosse feita no analisador. Isso pode ser adicionado, mas não vejo por que é melhor do que corrigir o formato do arquivo de dados.

Suponho que você não queira simplesmente que os valores de cores e números sejam impressos, como esse script faz. Você colocaria seu próprio código em cada uma das print linhas.

O $junk vem da minha suposição de que o dígito antes da (s) letra (s) colorida (s) pode ser significativo. Eu estou usando isso para ajudar o parser a fazer o que ele quer. Se você tiver um uso real para esse dígito, poderá renomear a variável $junk para ter significado semântico. É apenas "lixo" para mim, porque não sei o que o valor significa.

por 27.12.2014 / 00:33