Из gpx в файл csv

Предположим, что это обычные файлы без пробелов, символов новой строки, кавычек, обратной косой черты или недопустимых символов в их путях:

find /target/dir/ -type f \
  | awk '{t=$0; gsub(/\/[^/]*$/, "", t); if(a[t]++ < 4) print}' \
  | xargs rm --

См. комментарии ниже, чтобы узнать, как вы могли бы адаптировать его для более забавных имен файлов, если ваши утилиты поддерживают определенные расширения.

0
24.11.2018, 21:41
6 ответов

Вы можете использовать sed , чтобы вырезать ненужные символы:

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

s / [^ 0-9. T: -] \ + /, / g заменяет ненужные символы запятой

s / T / / заменяет символ T пробелом

s / ^, \ |, $ // g удаляет первую и последнюю запятую

1
28.01.2020, 02:15

Предположим, что f.xml - это наш ввод (действительный xml):

$ perl -MXML::DT -E 'dt("f.xml",
                         time=>sub{$a=father;
                                   $c =~ s/[TZ]/ /g;
                                   say "$a->{lat},$a->{lon},$c"}
                       )'
  • -MXML :: DT загрузить модуль XML :: DT (переводчик вниз xml)
  • dt (файл , time => sub {....}) : анализируйте файл и каждый раз, когда мы видим раз , выполняем соответствующий sub
  • $ a = Father : получаем атрибуты из отец
  • $ c : это текущее содержимое элемента

Предупреждение: я являюсь одним из авторов XML :: DT (устанавливается с cpan XML :: DT )

{ {1}}
0
28.01.2020, 02:15

этот ответ основан на введенных данных ...

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
1
28.01.2020, 02:15

Пожалуйста, не используйте регулярные выражения на основе решение, например awk или sed .

XML является контекстным, в то время как регулярные выражения не являются - , поэтому они НИКОГДА не могут работать должным образом, это в лучшем случае лишь небольшая хитрость .

Но у XML есть решение этой проблемы - он называется xpath , что позволяет «искать» контекстным способом.

Итак, возьмем ваш пример:

#!/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";
}

Что дает желаемый результат, но также будет обрабатывать множество совершенно корректных и семантически идентичных форм вашего XML.

Как с отступом:

<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>

Все в одной строке:

<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>

Другой стиль отступа:

<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>

Или даже:

<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>

Все они семантически идентичны, и следует анализировать одинаково способ. Надеюсь, совершенно ясно, что регулярное выражение для этого НАМНОГО сложнее, чем использование парсера XML.

Для краткости:

perl -MXML::Twig -0777 -e 'XML::Twig->new(twig_handlers=>{wpt=>sub{print join ",", $_->att("lat", $_->att("lon"),$_->first_child_text("time"), "\n" }})->parse(<>)'
2
28.01.2020, 02:15

GPX - это формат XML , поэтому вы не можете использовать awk или sed для его надежного анализа.

Вместо этого используйте что-то вроде 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

В качестве альтернативы:

$ xml sel -t -m '//wpt' -v 'concat(@lat, ",", @lon, ",", time)' -nl data.wpx
3
28.01.2020, 02:15
sed "s/[^0-9.:-]/ /g" j.txtK| sed -r "s/\s+/ /g"| sed -r "s/^\s+//g"|awk 'OFS=","{print $1,$2,$3" " $4}'

выход

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
0
05.06.2021, 19:48

Теги

Похожие вопросы