使用 Shell 从 KML 中提取海平面压力

3 xml awk geolocation

我目前正在做一个小项目;在一个名为weatherdata.kml的kml文件中,我想提取每个<Placemark>元素的海平面压力。我正在尝试解析有关海平面压力的信息并将其放入名为report.csv;的文件中。并每次在新行上打印海平面压力。

我认为这会起作用awk,到目前为止我已经尝试过:

 awk -F '[>,]' '/minSeaLevelPres/ {print $2}' report.csv
Run Code Online (Sandbox Code Playgroud)

但是当我在 shell 中运行此命令时,我得到以下信息:

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
Run Code Online (Sandbox Code Playgroud)

当我想得到这个时:

1002
1002
1002
1001
1001
1001
1001
1001
1001
1001
1001
1002
1002
1003
Run Code Online (Sandbox Code Playgroud)

我不知道如何摆脱</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>
Run Code Online (Sandbox Code Playgroud)

Cyr*_*rus 17

我建议使用一个可以正确处理XML的工具:

xmlstarlet select --template --value-of '//minSeaLevelPres' -n weatherdata.kml
Run Code Online (Sandbox Code Playgroud)

输出:

1002

看:xmlstarlet select --help


Mar*_*ler 5

KML 是一种 XML 语言。XML 不是一种可以可靠解析的语言awk。您可能很幸运拥有 \xe2\x80\x93 文件,它们的结构可能比语言定义允许的 \xe2\x80\x93 更可靠,但根本没有理由在 AWK 中编写自己的受限解析器当你得到一个可以使用不同工具始终有效的产品时。例如,当删除或添加换行符、注释时,您的内容就会损坏。

\n

我认为您只是想使用错误的工具。正如您awk在系统上安装的情况一样,您已经安装python了,然后您就有了一个 XML 解析器,并且可以在除了 Python 标准库之外没有外部代码的情况下编写一个非常小的程序写入您的 CSV。(记住,UNIX 哲学不是“你有一把锤子,现在一切都是钉子”,而是“你有用于不同目的的工具,为你的目的找到正确的工具”)。

\n
import sys\nimport xml.etree.ElementTree as ElemTree\n\nfname = sys.argv[1]\ntree = ElemTree.parse(fname)\nfor placemark in tree.getroot().iter("Placemark"):\n    print(placemark.find("minSeaLevelPres").text)\n
Run Code Online (Sandbox Code Playgroud)\n

就是这样。保存到文件,赋予文件执行权限(chmod o+x {filename}),然后就可以运行了/path/to/filename input.kml

\n

一般说明:

\n
\n

因为weatherdata.kml是一个很大的文件,

\n
\n

我不知道对您来说什么是“大”,但如果您最终编写了包含数百万行的 CSV,您将无法获得非常有效的数据表示形式。找出该数据的使用者支持哪些二进制格式,然后直接写入。很可能有一个 Python 库可以实现这一点。

\n