Do arquivo gpx para csv

0
<wpt lat="1.345529841" lon="103.7577152"><time>2010-01-01T00:00:00Z</time</wpt> 
<wpt lat="1.345529841" lon="103.7577152"><time>2010-01-01T00:00:00Z</time></wpt> 
<wpt lat="1.3982529841" lon="103.90877152"><time>2010-01-01T00:00:00Z</time></wpt> 

Eu tenho um arquivo como as linhas acima que precisavam ser convertidas em

         1.345529841,103.7577152,2010-01-01 00:00:00
         1.345529841,103.7577152,2010-01-01 00:00:00
         1.3982529841,103.90877152,2010-01-01 00:00:00
    
por RKR 09.02.2017 / 07:00

5 respostas

1

Você pode usar sed para remover os caracteres que não deseja:

sed 's/[^0-9.T:-]\+/,/g;s/T/ /;s/^,\|,$//g' file

s/[^0-9.T:-]\+/,/g está substituindo caracteres indesejados por uma vírgula

s/T/ / está substituindo o caractere T por um espaço

s/^,\|,$//g está removendo a primeira e a última vírgula

    
por 09.02.2017 / 09:43
3

O GPX é um formato XML , portanto, você não pode usar awk ou sed para analisá-lo de maneira confiável .

Em vez disso, use algo como XMLStarlet :

$ xml sel -t -m '//wpt' \
          -v '@lat' -o ',' -v '@lon' -o ',' \
          -v 'time' -nl data.gpx
1.345529841,103.7577152,2010-01-01T00:00:00Z
1.345529841,103.7577152,2010-01-01T00:00:00Z
1.3982529841,103.90877152,2010-01-01T00:00:00Z

Alternativamente:

$ xml sel -t -m '//wpt' -v 'concat(@lat, ",", @lon, ",", time)' -nl data.wpx
    
por 09.02.2017 / 10:38
1

esta resposta é baseada na entrada dada ...

awk -F"[<>\"]" '{print $3,$5,$9}' OFS=, input.txt | sed "s/[TZ]/ /g"
1.345529841,103.7577152,2010-01-01 00:00:00
1.345529841,103.7577152,2010-01-01 00:00:00
1.3982529841,103.90877152,2010-01-01 00:00:00
awk -F"[<>\"]" '{gsub(/T|Z/," ",$9);print $3,$5,$9}' OFS=, input.txt
    
por 09.02.2017 / 07:51
1

Por favor, por favor - não use uma solução baseada em expressões regulares, como awk ou sed .

XML é contextual, em que expressões regulares não são - para que eles NUNCA funcionem corretamente, eles são apenas um pouco hackeados .

Mas o XML tem uma solução para esse problema - ele é chamado de xpath , que permite "pesquisar" de maneira contextual.

Então, para dar o seu exemplo:

#!/usr/bin/perl

use warnings;
use strict;
use XML::Twig;

my $xml = XML::Twig -> new -> parsefile('your_file.xml'); 

foreach my $wpt ( $xml -> get_xpath('//wpt') ) {
   print join ",", $wpt -> att('lat'), 
                   $wpt -> att('lon'),
                   $wpt -> first_child_text('time'), "\n";
}

O que dá o resultado desejado, mas também irá lidar com uma variedade de formas do seu XML perfeitamente idênticas e semanticamente válidas.

Como recuado:

<xml>
  <wpt lat="1.345529841" lon="103.7577152">
    <time>2010-01-01T00:00:00Z</time>
  </wpt>
  <wpt lat="1.345529841" lon="103.7577152">
    <time>2010-01-01T00:00:00Z</time>
  </wpt>
  <wpt lat="1.3982529841" lon="103.90877152">
    <time>2010-01-01T00:00:00Z</time>
  </wpt>
</xml>

Tudo em uma única linha:

<xml><wpt lat="1.345529841" lon="103.7577152"><time>2010-01-01T00:00:00Z</time></wpt><wpt lat="1.345529841" lon="103.7577152"><time>2010-01-01T00:00:00Z</time></wpt><wpt lat="1.3982529841" lon="103.90877152"><time>2010-01-01T00:00:00Z</time></wpt></xml>

Outro estilo de recuo:

<xml>
  <wpt
      lat="1.345529841"
      lon="103.7577152">
    <time>2010-01-01T00:00:00Z</time>
  </wpt>
  <wpt
      lat="1.345529841"
      lon="103.7577152">
    <time>2010-01-01T00:00:00Z</time>
  </wpt>
  <wpt
      lat="1.3982529841"
      lon="103.90877152">
    <time>2010-01-01T00:00:00Z</time>
  </wpt>
</xml>

Ou até mesmo:

<xml
><wpt
lat="1.345529841"
lon="103.7577152"
><time
>2010-01-01T00:00:00Z</time></wpt><wpt
lat="1.345529841"
lon="103.7577152"
><time
>2010-01-01T00:00:00Z</time></wpt><wpt
lat="1.3982529841"
lon="103.90877152"
><time
>2010-01-01T00:00:00Z</time></wpt></xml>

Todos são semanticamente idênticos e devem ser analisados da mesma maneira. Espero que esteja bastante claro que uma expressão regular para fazer isso é MUITO mais complicada do que apenas usar um analisador XML.

Para ser conciso:

perl -MXML::Twig -0777 -e 'XML::Twig->new(twig_handlers=>{wpt=>sub{print join ",", $_->att("lat", $_->att("lon"),$_->first_child_text("time"), "\n" }})->parse(<>)'
    
por 10.02.2017 / 10:08
0

Assumindo que f.xml é nossa entrada (um xml válido):

$ perl -MXML::DT -E 'dt("f.xml",
                         time=>sub{$a=father;
                                   $c =~ s/[TZ]/ /g;
                                   say "$a->{lat},$a->{lon},$c"}
                       )'
  • -MXML::DT load XML :: módulo DT (xml down translator)
  • dt( file, time => sub{....}) : analisar arquivo e toda vez que vermos um time executar o correspondente sub
  • $a=father : obtenha os atributos do pai
  • $c : é o conteúdo do elemento atual

Atenção: Eu sou um dos autores do XML :: DT (instale com cpan XML::DT )

    
por 10.02.2017 / 12:45

Tags