Modifique um arquivo SVG com base em informações em um arquivo CSV

2

Eu tenho um arquivo SVG do mapa dos EUA e quero adicionar cores a ele. Porque levaria muito tempo, pensei que poderia usar um script bash. Eu também tenho outro arquivo contendo os estados e as cores que pertencem a eles.

Arquivo SVG:

<g id="hi">
    <title>Hawaii</title>
    <path class="state hi" d="m 233.08751,519.30948 ... z" id="HI" />
</g>

Arquivo CSV

HI, blue

O que eu quero:

<g id="hi" style="fill:blue;">
        <title>Hawaii</title>
        <path class="state hi" d="m 233.08751,519.30948 ... z" id="HI" />
    </g>

Eu achei que poderia usar grep ou sed , mas realmente não sei por onde começar.

    
por M-Reda Daoudi 29.11.2015 / 21:28

4 respostas

2

Usando o bash e o GNU sed:

while IFS=",$IFS" read id color
do
    sed -i "s/g id=\"${id,,}\"/& style=\"fill:$color;\"/g" file.svg
done <file.csv

Depois disso, file.svg se parece com:

<g id="hi" style="fill:blue;">
    <title>Hawaii</title>
    <path class="state hi" d="m 233.08751,519.30948 ... z" id="HI" />
</g>

Como funciona

  • while IFS=",$IFS" read id color; do

    Isso inicia um loop while lendo as variáveis id e color . Adicionamos uma vírgula a IFS para que a entrada seja dividida em vírgulas e em espaço em branco.

  • sed -i "s/g id=\"${id,,}\"/& style=\"fill:$color;\"/g" file.svg

    Isso faz uma atualização no local do arquivo.svg. Isso usa o bash para converter id para minúsculas: ${id,,} . Ele procura a string g id="${id,,}" e a substitui por g id="${id,,} style="fill:$color;" .

    Nota: $id e $color são substituídos diretamente em um comando sed. Você deve fazer isso somente se confiar na fonte do arquivo file.csv.

  • done <file.csv

    Isso conclui o loop while e instrui a leitura de file.csv .

BSD (OSX)

Se você estiver em um sistema BSD, precisamos fazer uma pequena alteração no comando sed:

while IFS=",$IFS" read id color
do
    sed -i "" "s/g id=\"${id,,}\"/& style=\"fill:$color;\"/g" file.svg
done <file.csv
    
por 29.11.2015 / 21:58
2

Usando o Perl e seu xsh :

perl {
    open my $FH, '<', 'states.csv' or die $!;
    $h->{lc $1} = "$2;" while <$FH> =~ /(.*),\s*(.*)/;
};

open map.xml ;
for //g set @style concat("fill:", xsh:lookup('h', @id));
save :b ;
    
por 29.11.2015 / 21:56
1

usando sed, duas vezes:

</tmp/states.csv tr "[A-Z]" "[a-z]" | \
sed -n 's/^\([a-z]\{2\}\), \([^ ]*\)$/s@<g id="">@<g id="" style="fill:;">@/p' >/tmp/script.sed
sed -f /tmp/script.sed /tmp/source.svg

A primeira linha cria um script sed (/tmp/script.sed) e a segunda linha o implementa. Assume que sua lista de estados está salva em /tmp/states.csv e seu arquivo svg em /tmp/source.svg.

    
por 29.11.2015 / 22:04
0
tr   \[:upper:] \[:lower:] <csv.file | sort -bt, -uk1,1   |
sed  -e'\|^ *\([[:alpha:]]\{2\}\) *, *\([[:alpha:]]\{1,\}\) *$|!d' \
     -e's||s/\(<g id=""\)>/\1 style="fill:;">/;t|' |
sed  -f- svg.file
    
por 30.11.2015 / 00:49