0

I had some time to try and learn more SED this week and have been experiment with the following sample code:

    </td>
    <td>
        <h4 class="text-danger" style="display: inline;">**Rádio Club 88 FM**</h4>
        <br>
        <b></b><br>

        <br>Genres: various<!--
        <br><samp>19 http://67.228.135.41:8216/listen.pls shoutcast1 audio/mpeg</samp>
        <div id="jplayer_inspector_19"></div>-->
    </td>
    <td width="120" class="text-right hidden-xs">
        <p>
        24 Listeners<br>
         128 Kbps<br>
        </p>
        <a style="margin:1px" class="btn btn-default btn-xs" onClick="ga('send', 'event', 'tunein', 'playpls', 'http://67.228.135.41:8216/listen.pls');" href="/servers/tools/playlistgenerator/?u=http://67.228.135.41:8216/listen.pls&amp;t=.pls">PLS</a>
        <a style="margin:1px" class="btn btn-default btn-xs" onClick="ga('send', 'event', 'tunein', 'playm3u', 'http://67.228.135.41:8216/listen.pls');" href="/servers/tools/playlistgenerator/?u=http://67.228.135.41:8216/listen.pls&amp;t=.m3u">M3U</a>
        <a style="margin:1px" class="btn btn-default btn-xs" onClick="ga('send', 'event', 'tunein', 'playram', 'http://67.228.135.41:8216/listen.pls');" href="/servers/tools/playlistgenerator/?u=http://67.228.135.41:8216/listen.pls&amp;t=.ram">RAM</a>
        <a style="margin:1px" class="btn btn-default btn-xs" onClick="window.open('/player/?mount=http://67.228.135.41:8216/listen.pls&amp;title=Rádio Club 88 FM&amp;website=http://www.shoutcast.com','PopupPlayer','width=400,height=300'); ga('send', 'event', 'tunein', 'playpopup', 'http://67.228.135.41:8216/listen.pls');" href="#">FLA</a>
    </td>

My goal was to have the following outcome which would be parsed from two different line and put back together using the hold space

Suggested Output

should be the the contents of first match a tab as a seprerator and the second match

Soundzrise RADIO  \t http://94.23.66.114:8122
::| ([bAm BaM RADIO]) |:: \t http://www.bambamradio.com:8888
NRGRadio.nl \t http://188.138.56.235:27914 

I have both SED command that work

First Match

is the H4 line, i am extracting what is between the ">" and "<"  
COMMAND =sed -rne 's/.*<h4 class=.*>(.*)<\/h4>/\1/ip'

Second Match

is the http address in line containing "playpls" - 
Command =  sed -rne "s/.*playpls', '(.*)\/listen.pls'.*/\1/p"

My problem is combining then with proper use of the hold space. I have tried several variations. however none on then have work. I.e.

sed -rne 's/.*<h4 class=.*>(.*)<\/h4>/\1/i;h' -e "s/.*playpls', '(.*)\/listen.pls'.*/\1/;G;p"
  • 1
    Could you edit your question and show the output you expect from your example? The one you show has nothing to do with the input. Also, explain exactly what you are trying to match. – terdon Sep 23 '15 at 14:53
0

If you must use sed (rather than, say XSLT), or if you just want to better understand how to use hold space, then you'll want to do something like:

Save the H4 line to hold space:

/<h4 /h

When you see the playpls line, append the hold space:

/ 'playpls',/{
G
# do something here
}

Now, your pattern space should look something like

<a style="margin:1px" class="btn btn-default btn-xs" onClick="ga('send', 'event', 'tunein', 'playpls', 'http://67.228.135.41:8216/listen.pls');" href="/servers/tools/playlistgenerator/?u=http://67.228.135.41:8216/listen.pls&amp;t=.pls">PLS</a>
<h4 class="text-danger" style="display: inline;">**Rádio Club 88 FM**</h4>

(including that embedded newline). So you can replace that comment with something like

s/.*'playpls', '\([^']*\)'.*\n.*<h4 [^>]*>\([^<>]*\).*/\2\t\1/p

and run your script with sed -n so that only the pattern spaces that match the substitution get printed.

In fact, given you'll get no match unless you appended the hold space, you can do all this without braces:

#!/bin/sed -rnf
# I've assumed GNU sed above

/<h4 /h
/ 'playpls',/G
/\n/s/.*'playpls', '([^']+)'.*\n.*<h4 [^>]+>([^<>]+).*/\2\t\1/p
  • Excellent! so my mistake was that i was trying move the results of each the hold spaces to the pattern space. rather than combining both lines and then extracting needed elements. Don't know what my logic assumed that my method would have worked. thank you. – user68650 Sep 23 '15 at 17:42
0

I recommend you do some preparatory work for sed. Instead of going multi-line at all. grep for both lines and then fold them together using paste. That gives you lines where both matches are on the same line and not much else. From there it should be easy to pick both references without going multi-line at all.

Example input:

# echo 'first_a foo second_A bar first_b junk second_B crap' | tr ' ' '\n'
first_a
foo
second_A
bar
first_b
junk
second_B
crap

Work it like this:

# echo 'first_a foo second_A bar first_b junk second_B crap' | tr ' ' '\n' | \
    grep -E 'first|second' | \
    paste - -  | \
    sed -e 's/first_\([a-z]*\)[^a-z].*second_\([a-z]*\)/\1 \2/'
a A
b B

The point being that the paste is a really good tool.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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