シェルを使ってKMLから海面気圧を抽出する

シェルを使ってKMLから海面気圧を抽出する

<Placemark>私は現在Weatherdata.kmlというkmlファイルで小規模プロジェクトを進めています。各要素の海面気圧を抽出したいと思います。私は海面気圧に関する情報を解析して、次のようなreport.csvファイルに入れようとします。そして毎回新しいラインに海面圧力を印刷します。

私はこれがうまくいくと思いますawk。これまでに試したことは次のとおりです。

 awk -F '[>,]' '/minSeaLevelPres/ {print $2}' report.csv

ただし、シェルでこのコマンドを実行すると、次の結果が表示されます。

1002</minSeaLevelPres
1002</minSeaLevelPres
1002</minSeaLevelPres
1001</minSeaLevelPres
1001</minSeaLevelPres
1001</minSeaLevelPres
1001</minSeaLevelPres
1001</minSeaLevelPres
1001</minSeaLevelPres
1001</minSeaLevelPres
1001</minSeaLevelPres
1002</minSeaLevelPres
1002</minSeaLevelPres
1003</minSeaLevelPres

私がこれを得たいとき:

1002
1002
1002
1001
1001
1001
1001
1001
1001
1001
1001
1002
1002
1003

私はそれを取り除く方法を知りません</minSeaLevelPres。誰でも助けることができますか?

以下はランドマーク要素のいくつかの例です。weatherdata.kml

 <Placemark>
        <styleUrl>#ex</styleUrl>
        <lat>19.2</lat>
        <lon>-24.1</lon>
        <stormName>NINE</stormName>
    <stormNum>10</stormNum>
    <basin>AL</basin>
        <stormType>LO</stormType>
        <intensity>20</intensity>
           <intensityMPH>23</intensityMPH>
           <intensityKPH>37</intensityKPH>
           <minSeaLevelPres>1002</minSeaLevelPres>
           <atcfdtg>2020082350</atcfdtg>
        <dtg>0000 UTC JAN 07</dtg>
       </Placemark>

答え1

XMLを正しく処理できるツールを使用することをお勧めします。

xmlstarlet select --template --value-of '//minSeaLevelPres' -n weatherdata.kml

出力:

1002

望むより:xmlstarlet select --help

答え2

KMLはXML言語です。 XMLは安定して解析できる言語ではありませんawk。持っているファイルは幸運かもしれません。そのファイルの構造は、言語定義が許可するよりも安定している可能性があります。しかし、他のツールと一貫して動作するファイルを取得すると、AWKデバイスで制限された解析を直接書く理由はありません。たとえば、改行、コメントを削除または追加すると、コンテンツが破損します。

私の考えでは、あなたが間違ったツールを使用しようとしていると思います。おそらくawk、システムにXMLパーサーがインストールされていて、pythonPythonの標準ライブラリ以外の外部コードなしでCSVを書く非常に小さなプログラムを書くことができます。 (UNIXの哲学は、「ハンマーを持っており、今はすべてが不可能です」ではなく、「他の目的のためのツールがあるので、目的に合ったツールを見つける」ということを覚えておいてください。)

import sys
import xml.etree.ElementTree as ElemTree

fname = sys.argv[1]
tree = ElemTree.parse(fname)
for placemark in tree.getroot().iter("Placemark"):
    print(placemark.find("minSeaLevelPres").text)

それはすべてです。ファイルに保存し、ファイル実行権限(chmod o+x {filename})を付与して実行します/path/to/filename input.kml

一般的なガイドライン:

Weatherdata.kmlは容量の大きいファイルなので、

「大きな」ものは何であるかはわかりませんが、何百万もの行を含むCSVを作成すると、データを非常に効率的に表現することはできません。このデータの消費者がどのバイナリ形式をサポートしているかを調べて、自分で書いてください。おそらくこれを達成できるPythonライブラリがあります。

答え3

awk他の人と同じようにXMLを使用しているので、私はこれをお勧めしません。ただし、何らかの理由でこのコマンドを使用したい場合、ファイルが機能する形式でフォーマットされている場合、またはプレーンawkテキストファイルの場合はより良い形式になっている場合は、問題では機能しないという質問にこのコマンドがある理由を正確に説明します。 :

コマンドには、>またはに,示されているフィールド区切り記号があります。[>,]

awk -F '[>,]' '/minSeaLevelPres/ {print $2}' report.csv

つまり、2番目のフィールドは、ファイル内の2文字のうちの1番目のインスタンスに続くフィールドであり、>文字列を含む行からminSeaLevelPres{print $2}られる内容を正確に提供します。

1002</minSeaLevelPres>

この特定の場合に提供したサンプルテキストからコンテンツを取得するには、1002次のものが必要です。

awk -F '[><]' '/minSeaLevelPres/ {print $3}' weatherdata.kml

これにより、フィールド区切り文字がまたは>に設定され、上記のコマンドから3番目のフィールドのみが印刷され、目的の結果が得られます<10021002

1002

繰り返しますが、XMLや議論の目的でHTMLファイルで使用することはお勧めできませんawk。ただし、コマンドが機能しない理由と、次のような場合にコマンドがどのように機能するかを説明するために、この答えを提供するだけです。プレーンテキストファイルで動作しています。awk今後ご利用の際に参考にしてください。

答え4

使用幸せ(以前のPerl_6)

~$ raku -MXML -e 'my $xml=open-xml($*ARGFILES.Str); 
        .put for $xml.lookfor(:TAG<minSeaLevelPres>)>>.[0];' weatherdata.kml

上記は、Perlシリーズのプログラミング言語であるRakuで書かれた答えです。XMLコマンドラインフラグを使用して、コマンドラインからRakuモジュールをロードできます-MXML。次に、lookfor(再帰要素の検索)コマンドを使用してXMLを解析します.最後のステップ>>.[0] または.map(*.[0])ラベルマッピングでは、その中に含まれる値のみが返されます。

weatherdata.kmlファイルに単純な位置表示、浮動位置表示、または押し出し位置表示のいずれか、またはすべてがあるかどうかに関係なく、ファイルが実際にどのように見えるかは不明です。上記のコマンドは単に:TAG<minSeaLevelPres>再帰的に検索し、1行に1つの値を出力します。

入力例については、次を参照してください。

https://developers.google.com/kml/documentation/KML_Samples.kml

出力例(TAG上記をテストに変更:TAG<tessellate>):

1
0
1
1
1
1
1
1
1
1

https://github.com/raku-community-modules/XML
https://raku.org/

関連情報