Como remover tags semelhantes a XML da entrada?

3

Estou atualizando meu arquivo .bashrc para mostrar o tempo que estou usando a linha

lynx -dump "http://wxdata.weather.com/wxdata/weather/local/14225?cc=*&unit=f&dayf=1" | grep -A 2 -m 1 "<tmp>"

O que me dá uma saída de

    <tmp>48</tmp>
    <flik>46</flik>
    <t>Fair</t>

Eu preciso adicionar | sed xxxxxx para remover tudo, menos o texto, para que fique assim

48
46
Fair

Eu tentei ler sobre isso, mas .. minha cabeça começa a girar e eu não consigo encontrar ninguém ou qualquer coisa que diz para fazer isso você tem que usar isso .... Eu só encontro coisas como "para remover isso você coloca 's/\.[^\.]*$//' " mas eles nunca dizem o que está fazendo eu não posso dizer .. ok ... eu preciso mudar isso para que assim funcione do jeito que eu quero. Tudo que vejo é um arranhão de galinha: D

Alguém poderia descobrir o que eu preciso usar para minha linhagem sed e, se possível, explicar como o arranhão do frango está realmente tirando o que eu preciso tirar?

Se for demais, eu ficaria feliz apenas pela linha que eu poderia usar e eu vou usar isso no .bashrc , então se você puder manter isso em mente ... Eu notei que você tem que ser muito cuidado com o uso de " and '

Esta é a linha que estou modificando, que não funciona mais

weather ()
{
declare -a WEATHERARRAY
WEATHERARRAY=( 'lynx -dump "http://www.google.com/search?hl=en&lr=&client=firefox-a&rls=org.mozilla_en-US_official&q=weather+{}&btnG=Search" | grep -A 5 -m 1 "Weather for" | sed 's;\[26\]Add to iGoogle\[27\]IMG;;g'')
echo ${WEATHERARRAY[0]} ${WEATHERARRAY[1]} ${WEATHERARRAY[2]} ${WEATHERARRAY[3]}
echo -ne "Today:" ${WEATHERARRAY[4]} "-" ${WEATHERARRAY[9]} "\t" ${WEATHERARRAY[5]} "-" ${WEATHERARRAY[10]} "\t" ${WEATHERARRAY[6]} "\t" ${WEATHERARRAY[7]}

Eu acho que vou ter que mudar para ficar assim

weather ()
{
declare -a WEATHERARRAY
WEATHERARRAY=( 'lynx -dump "http://wxdata.weather.com/wxdata/weather/local/14225?cc=*&unit=f&dayf=1" | grep -A 2 -m 1 "<tmp>" | sed 'sed commands'')
echo -ne "Today: ${WEATHERARRAY[2]} "-"  ${WEATHERARRAY[0]}"º" "Feels Like:" ${WEATHERARRAY[1]}"º" 

Qualquer ajuda seria muito apreciada.

    
por John Orion 06.05.2016 / 10:37

3 respostas

2

Eu finalmente consegui trabalhar como eu queria. Eu tenho que dar crédito e obrigado a efthialex por suas explicações. Sua solução não funcionou para minha situação, mas a informação que ele deu com certeza me ajudará no futuro.

Eu também tenho que agradecer ao the_velour_fog. Ele quase conseguiu trabalhar do jeito que eu queria ... nós éramos próximos e ele provavelmente teria conseguido se continuássemos tentando.

A resposta real veio de steeldriver Ele foi capaz de chegar com a melhor solução e agora funciona exatamente como eu queria. Eu marcaria sua resposta como correta, mas ... rsrs foi o único que postou a ajuda em um comentário que acabou sendo a melhor solução. A solução final e a mudança no código foi a seguinte

weather ()
{
declare -a WEATHERARRAY
mapfile -t WEATHERARRAY < <(lynx -dump "http://wxdata.weather.com/wxdata/weather/local/14225?cc=*&unit=f&dayf=1" | xmlstarlet sel -T -t -m "/weather/cc" -c "tmp" -n -c "flik" -n -c "t" -n) ;
echo -ne "Today:" ${WEATHERARRAY[2]} "-" ${WEATHERARRAY[0]}"º" "Feels Like:" ${WEATHERARRAY[1]}"º" 
}

Obrigado mais uma vez, isso é o que você me ajudou a criar:

    
por John Orion 07.05.2016 / 04:00
2

Acabei de escrever e testar isso e funciona para mim, supondo que seu texto esteja em um arquivo chamado: text_for_sed.txt

comando:

sed -n "/<tmp>\([[:digit:]]\{2\}\)<\/tmp>/{
    s/<tmp>\([[:digit:]]\{2\}\)<\/tmp>//p
    n
    s/<flik>\([[:digit:]]\{2\}\)<\/flik>//p
    n
    s/<t>\([[:alpha:]]\+\)<\/t>//p
}" text_for_sed.txt

saída

48
46
Fair

se o grep estiver produzindo a saída, você irá canalizá-lo para sed

<your grep command> | sed -n "/<tmp>\([[:digit:]]\{2\}\)<\/tmp>/{
    s/<tmp>\([[:digit:]]\{2\}\)<\/tmp>//p
    n
    s/<flik>\([[:digit:]]\{2\}\)<\/flik>//p
    n
    s/<t>\([[:alpha:]]\+\)<\/t>//p
}"

Eu sei que isso é complicado, tentei pensar em uma maneira melhor (mais simples) - se você pudesse fazer isso em várias passagens grep --only seria mais fácil, mas em uma única passagem sed é a única maneira que eu sei fazer isso.

    
por the_velour_fog 06.05.2016 / 11:13
2
#!/bin/bash 

data=$(lynx -dump "http://wxdata.weather.com/wxdata/weather/local/14225?cc=*&unit=f&dayf=1" | grep -A 2 -m 1 "<tmp>")

for pattern_to_find in tmp flik t
do
    echo $data | tr " " "\n" | sed -ne "/<$pattern_to_find>/s#\s*<[^>]*>\s*##gp"
done

Resultado

51
51
Mostly

Explicação:

echo $data | tr " " "\n" | sed -ne '/<pattern_to_find>/s#\s*<[^>]*>\s*##gp'

tr " " "\n" - substitui espaços em branco por \n

sed part:

Item da lista

n - suprime a impressão de todas as linhas

e - script

/<pattern_to_find>/ - encontra linhas que contêm um padrão especificado que pode ser, por exemplo, <tmp>

A próxima é a parte de substituição s///p que remove tudo, exceto o valor desejado, onde / é substituído por # para melhor legibilidade:

s#\s*<[^>]*>\s*##gp

\s* - inclui espaços em branco se existir (igual ao final) <[^>]*> representa <xml_tag> como causa alternativa de regex não ganancioso <.*?> não funciona para sed g - substitui tudo, por exemplo fechando xml </xml_tag> tag

Source @vldbnc

    
por efthialex 06.05.2016 / 11:17