Atualmente estou trabalhando em um pequeno projeto; em um arquivo kml chamado weatherdata.kml, gostaria de extrair a pressão do nível do mar para cada <Placemark>
elemento. Estou tentando analisar as informações sobre a pressão do nível do mar e colocá-las em um arquivo chamado report.csv
; e imprima a pressão ao nível do mar em uma nova linha a cada vez.
Eu acho que isso funcionaria awk
e até agora eu tentei isso:
awk -F '[>,]' '/minSeaLevelPres/ {print $2}' report.csv
Mas quando executo este comando no shell, recebo isso:
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
quando eu quero pegar isso:
1002
1002
1002
1001
1001
1001
1001
1001
1001
1001
1001
1002
1002
1003
Não consigo descobrir como me livrar de </minSeaLevelPres
. Alguém saberia ajudar?
Abaixo está um exemplo de parte de um elemento de marcador emweatherdata.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>
Sugiro usar uma ferramenta que possa manipular XML corretamente:
Resultado:
Ver:
xmlstarlet select --help
KML é uma linguagem XML. XML não é uma linguagem com a qual você possa analisar de forma confiável
awk
. Você pode ter sorte com os arquivos que possui – eles podem ser estruturados de forma mais confiável do que a definição da linguagem permite – mas simplesmente não há razão para escrever seu próprio analisador restrito em AWK quando você obtém um que funciona sempre, com ferramentas diferentes. Suas coisas quebram quando as coisas removem ou adicionam quebras de linha, comentários, por exemplo.Acho que você está simplesmente tentando usar a ferramenta errada. Tão provável quanto você
awk
instalou em seu sistema é que vocêpython
instalou, por exemplo, e então você teria um analisador XML e poderia, sem nenhum código externo além da biblioteca padrão do Python, escrever um programa realmente pequeno que escreve seus CSVs. (Lembre-se, a filosofia UNIX não é "você tem um martelo, agora tudo é um prego", mas "você tem ferramentas para diferentes propósitos, encontre a ferramenta certa para seu propósito").E é isso. Salve em um arquivo, dê o direito de execução do arquivo (
chmod o+x {filename}
), e então você pode executar/path/to/filename input.kml
.Observação geral:
Não sei o que constitui "grande" para você, mas se você acabar escrevendo um CSV com vários milhões de linhas, não obterá uma representação de dados muito eficiente. Descubra quais formatos binários o consumidor desses dados suporta e escreva isso diretamente. É provável que exista uma biblioteca Python para isso.
Como os outros, eu não recomendaria fazer isso
awk
porque você está trabalhando com XML. No entanto, se você quiser usá-lo por algum motivo e seu arquivo foi formatado de tal forma queawk
funcionaria ou melhor ainda, se fosse um arquivo de texto simples, então vou mostrar exatamente porque o comando que você tem na sua pergunta não estava funcionando:Seu comando tem o separador de campo como
>
ou,
conforme indicado por[>,]
O que isso significa é que o segundo campo é o que vem após a primeira instância de qualquer um desses dois caracteres que estão em seu arquivo
>
e na(s) linha(s) que contém a stringminSeaLevelPres
,{print $2}
fornecerá exatamente o que você estava obtendo:Neste caso específico, se você quiser apenas obter
1002
do texto de exemplo que você forneceu, o que você precisaria é issoIsso definiria o separador de campo como
>
ou<
o que faria1002
e apenas1002
o terceiro campo que seria impresso a partir do comando acima e daria o que você deseja:Novamente, não estou recomendando o uso de
awk
um XML ou, para fins de argumentação, um arquivo HTML, mas estou apenas fornecendo esta resposta para mostrar por que seu comando não estava funcionando e o que você faria para que funcionasse se você estava operando em um arquivo de texto simples. Você pode fazer referência a isso quando usarawk
no futuro.Usando Raku (anteriormente conhecido como Perl_6)
Acima está uma resposta codificada em Raku, um membro da família Perl de linguagens de programação. Você pode carregar o
XML
Módulo Raku na linha de comando com o-MXML
sinalizador de linha de comando. Em seguida, analise o XML, usando olookfor
comando (pesquisa de elemento recursivo). Na etapa final,>>.[0]
ou.map(*.[0])
mapeia na tag, retornando apenas o valor contido nela.Observe que não está claro como seu
weatherdata.kml
arquivo realmente se parece, se ele tem um ou todos os marcadores simples, flutuantes e/ou extrudados. O comando acima simplesmente procura:TAG<minSeaLevelPres>
recursivamente, gerando valores um por linha.Exemplo de entrada, consulte:
https://developers.google.com/kml/documentation/KML_Samples.kml
Saída de amostra (altere
TAG
acima:TAG<tessellate>
para testar):https://github.com/raku-community-modules/XML
https://raku.org/