gpx에서 csv 파일로

gpx에서 csv 파일로
<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> 

위와 같은 줄을 다음으로 변환해야 하는 파일이 있습니다.

         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

답변1

GPX는 XML 형식입니다.awk이므로 안정적으로 사용 하거나 sed구문 분석 할 수 없습니다 .

대신 다음과 같은 것을 사용하십시오.XML 스타(XML 문서의 형식이 올바르고 오류가 없다고 가정):

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

또는:

xmlstarlet sel -t -m '//wpt' -v 'concat(@lat, ",", @lon, ",", time)' -nl data.wpx

다음을 사용할 수도 있습니다 xq(부분적 yq으로https://kislyuk.github.io/yq/):

$ xq -r '.. | .wpt? // empty | .[] | map(values) | @csv' 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"

그러면 모든 노드를 찾아 wpt모든 속성과 하위 노드의 값을 추출하고 그로부터 CSV 출력을 생성합니다.

열을 다시 정렬해야 하거나 각 열에 사용할 값을 선택해야 하는 경우에도 이렇게 할 수 있습니다.

$ xq -r '.. | .wpt? // empty | .[] | [."@lat", ."@lon", .time] | @csv' 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"

답변2

제발 - 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(<>)'

답변3

다음을 사용하여 원하지 않는 문자를 제거 할 수 있습니다 sed.

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

s/[^0-9.T:-]\+/,/g원하지 않는 문자를 쉼표로 바꾸기

s/T/ /T문자가 공백으로 대체됩니다.

s/^,\|,$//g첫 번째와 마지막 쉼표 제거

답변4

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::DTXML::DT 모듈 로드(xml 다운 변환기)
  • dt( file, time => sub{....})time: 파일을 구문 분석하고 해당 하위 파일이 실행되는 것을 볼 때마다
  • $a=father : 아버지로부터 속성 가져오기
  • $c: 현재 요소 콘텐츠입니다.

cpan XML::DT경고: 저는 XML::DT(다음을 사용하여 설치됨)의 작성자 중 한 명입니다.

관련 정보