3

I'm updating my .bashrc file to show weather I'm using the line

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

Which gives me an output of

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

I need to add | sed xxxxxx to strip away everything but the text so it looks like this

48
46
Fair

I have tried to read up on it but .. my head starts to spin and I can't find anyone or anything that says to do this you have to use this .... I only find things like "to remove this you put 's/\.[^\.]*$//'" but they never say what its doing so I can't say .. ok ... I need to change this to that so it works the way I want. All I see is chicken scratch :D

Could someone figure out what I need to use for my sed line and if possible explain how the chicken scratch is actually stripping what I need to strip?

If its too much of an explination I would be happy just for the line I could use and I will be using this in the .bashrc so if you can keep that in mind... I noticed that you have to be real careful with the use of " and '

This is the line I'm modifying which no longer works

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+{$1}&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]}

I figure I will have to change it to look like this

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]}"º" 

Any help would be greatly appreciated.

  • IMHO you would be better advised to use a proper parser for that e.g. pipe the output of the lynx dump straight to xmlstarlet sel -T -t -m "/weather/cc" -c "tmp" -n -c "flik" -n -c "t" -n – steeldriver May 6 '16 at 13:47
  • I tried this and got this as a result: -:2.9: Extra content at the end of the document <flik>64</flik> ^ – John Orion May 6 '16 at 18:45
  • 1
    What did you try exactly? 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 – steeldriver May 6 '16 at 19:13
  • Ok now I got it working ... silly me ... forgot to remove the grep part :(... but I still have one issue.. when I just run the command from a prompt I see it properly .. with the two words if there are two ... but when I use it in my .bashrc I still only see the first word... but this is the closest yet because when I do it in terminal I do see everything .. just need to figure out what is stopping the second word from showing in my bashrc. This should be a bit easier because I'm not dealing with the nightmare of chicken scratch .. man even with the help I still feel lost with sed :D – John Orion May 6 '16 at 20:00
  • 1
    Probably because of the way you're constructing the array: I'd suggest using mapfile (or its synonym readarray) e.g. 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 "${WEATHERARRAY[2]}" – steeldriver May 6 '16 at 20:09
2

I have just written and tested this and it works for me, assuming your text is in a file called: text_for_sed.txt

command:

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

output

48
46
Fair

if grep is producing the output then you would pipe it into sed

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

I know this is complicated looking, I tried to think of a better (simpler) way - if you could do it in multiple passes grep --only would be easier but in one pass sed is the only way I know how to do it.

  • I tried this and it gave me only tmp and flik temps .. the "fair" didn't show – John Orion May 6 '16 at 9:27
  • are you sure that greps output is consistant? It worked for me with the text you provided. I would recommend simplifying the regex on the last line and see if that prints anything – the_velour_fog May 6 '16 at 9:31
  • well the "fair" now is "partly cloudy" but the setup is the <t> </t> still shows if I run the command without the sed. I removed the last line of sed section and it still only printed the value in tmp and flik. but its almost 6am here and I have to leave at 11 .. i think I need a little sleep :D – John Orion May 6 '16 at 9:42
  • 1
    @JohnOrion ah that is probably the problem, the s/<t>\([[:alpha:]]\+\)<\/t>/\1/p regex won't match if its not a single word like "fair", you could try s/<t>\(.\+\)<\/t>/\1/p – the_velour_fog May 6 '16 at 9:48
  • so far this has been the closest to getting me what I want to show on the screen ... this now works but only shows the first word if there is two .. like right now its saying Partly Cloudy but I only get Partly. I have played around and still :( totally lost :( .. I can't figure out how to get the second word to show and if I could then I would have to make sure it didn't fail if it went back to a single word – John Orion May 6 '16 at 19:30
2

I finally got it working like I want. I have to give credit and thanks to efthialex for his explanations. His solution didn't work for my situation but the information he gave will for sure help me in the future.

I also have to thank the_velour_fog. He almost got it working the way I wanted .. we were close and he probably would have got it if we kept trying.

The actual answer came from steeldriver He was able to come up with the best solution and now it works exactly like I wanted. I would mark his answer as correct but.. lol he was the only one who posted the help in a comment that ended up being the best solution. The final solution and change in code was as follows

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]}"º" 
}

Thanks again this is what you helped me to create:enter image description here

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

Output

51
51
Mostly

Explanation:

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

tr " " "\n" - replaces whitespaces with \n

sed part:

List item

n - suppress printing all lines

e - script

/<pattern_to_find>/ - finds lines that contain specified pattern what could be e.g.<tmp>

next is substitution part s///p that removes everything except desired value where / is replaced with # for better readability:

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

\s* - includes white-spaces if exist (same at the end) <[^>]*> represents <xml_tag> as non-greedy regex alternative cause <.*?> does not work for sed g - substitutes everything e.g. closing xml </xml_tag> tag

Source @vldbnc

  • Tried this but must not be putting it in the .bashrc file correctly .. ended up with Weather:bash: <tmp>45</tmp>: No such file or directory bash: <tmp>45</tmp>: No such file or directory bash: <tmp>45</tmp>: No such file or directory Today: - º Feels Like: º – John Orion May 6 '16 at 9:32
  • its very late and i need to get up in less than 5 hours so I think I'm going to take a brake for tonight.. I will look more at your post tomorrow and see if I can figure out where I went wrong. – John Orion May 6 '16 at 9:43
  • I updated my post, try this one – efthialex May 6 '16 at 9:52
  • Well I tried this as a script and I just get 3 lines that say line 7: <tmp>64</tmp>: No such file or directory I am giving you a helpful on it tho because your explanation was good and helped me understand a little better what is going on with those commands. I almost have the_velour_fog's solution working and may be able to get it to work now that I have the information from your post . It was much appreciated. – John Orion May 6 '16 at 18:42
  • @JohnOrion I fixed it. This is working now – efthialex May 7 '16 at 20:38

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.