[sed] [geektool] P2000 RSS feed in Sed, newline probleem

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • JiMiHeNdRiX
  • Registratie: Juni 2008
  • Laatst online: 03-10 08:25
Iemand met SED-kennis die me kan helpen?

Ik ben bezig om met Sed een nieuw Geektool-script te schrijven. Dat lukt ook aardig, d.w.z. het script draait netjes en toont precies de informatie die ik wil zien, echter het lukt me niet om een newline te krijgen. Alle informatie verschijnt dus in één bulk zonder nieuwe regels in Geektool. Het liefst wil ik op de plek waar in de bron de passage <![CDATA voorkomt (deze wordt nu uitgefilterd in regel 16 in het script) naar de volgende regel springen+extra lege regel ertussen. Ik heb tevergeefs een aantal dingen geprobeerd met / en \ en en \n en '$' en noem maar op, zoals:


code:
1
sed 's/CDATA/\'$'\n/g' |


en

code:
1
2
sed 's@\<\!\[CDATA\[@test \
 @g' |


Laatstgenoemde leverde wel een newline op, maar enkel voor het eerste voorkomen van CDATA, maar niet voor alle volgende voorkomens. De eerst genoemde oplossing zou juist op de Apple goed zou moeten werken, maar die doet het in zijn geheel niet.


code: Livep2000 rss feed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/bin/sh

URL="http://feeds.livep2000.nl/?r=12,13&d=1,2,4"

echo Bron: Livep2000.nl
echo

curl "$URL" | 
sed s/"<rss".*"+xml'\/>"//g |
sed 's@<link>[^<]*</link>@@g' |
sed 's@<pubDate>[^<]*</pubDate>@@g' |
sed 's@<guid[^<]*</guid>@@g' |
sed 's@<geo:long>[^<]*</geo:long>@@g' |
sed 's@<geo:lat>[^<]*</geo:lat>@@g' |
sed 's@<i [^<]*</i>@@g' |
sed 's@<!\[CDATA\[@@g' |
sed s/"<description>"/""/g |
sed s/"<\/description>"/""/g |
sed s/"<br\/>"//g |
sed s/"<item>"/""/g |
sed s/"<title>"/""/g |
sed s/"<\/item>"/""/g |
sed s/"<\/title>"/""/g |
sed s/"<\/channel>"/""/g |
sed s/"<\/rss>"/""/g |
sed s/"\]\]"/""/g |
fmt -100

Acties:
  • 0 Henk 'm!

  • vanaalten
  • Registratie: September 2002
  • Laatst online: 19:10
Even voor de toekomst:
Als je SED hulp nodig hebt, dan maak je het de medemens makkelijk als je het probleem isoleert tot het kleinst mogelijke:
1) maak een textfile met voorbeeld inputtekst
2) maak een textfile met gewenste outputtekst

Dat maakt het voor, bijvoorbeeld, mij makkelijker om het direct te proberen.

Voor dit probleem:
Inputtekst file test.txt:
code:
1
2
3
4
5
6
7
line 1
line 2<![CDATA[ voorkomt
line 3
<![CDATA[ voorkomt 
line 5
line 6<![CDATA[ voorkomt 
line 7 xxxxxxxx

Met script test.scr:
code:
1
2
sed 's@<!\[CDATA\[@test \
 @g' test.txt

(ik heb de escape voor '<' en '!' weggelaten)
... geeft output:
code:
1
2
3
4
5
6
7
8
9
10
line 1
line 2test 
  voorkomt
line 3
test 
  voorkomt 
line 5
line 6test 
  voorkomt 
line 7 xxxxxxxx

Overigens zou je, als dit niet betrouwbaar werkt, ook met de 'a' kunnen werken:
code:
1
2
sed '/<!\[CDATA\[/a\
' test.txt

... weet niet precies wat je er uit had willen hebben, maar met 'a' kan je regels appenden en dan komen er ook newlines bij.

Acties:
  • 0 Henk 'm!

  • JiMiHeNdRiX
  • Registratie: Juni 2008
  • Laatst online: 03-10 08:25
Inderdaad, daar heb je gelijk in. Ik had er niet aan gedacht om input en gewenste output in vereenvoudigde vorm te vermelden. Dat doe ik nu alsnog. De input zit niet in een textfile, maar wordt gedownload van internet en in een variabele in het script geplaatst. Input en huidig script zien er vereenvoudigd als volgt uit:

code:
1
2
3
4
5
6
#!/bin/sh

TEST="<[CDATA[regel1<[CDATA[regel2<[CDATA[regel3"

echo "$TEST" | 
sed 's@<\[CDATA\[@@g'


Bovenstaande instructie leidt tot de volgende output:

code:
1
regel1regel2regel3


Het gewenste resultaat is:

code:
1
2
3
4
5
regel1

regel2

regel3


Je ziet een verschil tussen jouw aanname en de feitelijke situatie (met excuses mijnerzijds;-)), nl. dat de input uit slechts één line bestaat en niet uit meerdere. Bovendien komt de passage <[CDATA meerdere keren voor in de line. Voorgestelde oplossingen lijken hier niet te werken. Kan je/iemand me adviseren hoe dit op te lossen?

Hopelijk heb ik probleem het nu duidelijk gemaakt. Daarnaast is het (helaas) zo dat er zich in de werkelijke input een uitroepteken tussen de < en [ bevindt, dus <![CDATA , waardoor Terminal ook over zijn nek gaat. Echter Geektool kan er wél gewoon mee omgaan. Vandaar dat ik in dit voorbeeld het uitroepteken gemakshalve maar weggelaten heb. Niet iedereen gebruikt immers Geektool.

Acties:
  • 0 Henk 'm!

  • vanaalten
  • Registratie: September 2002
  • Laatst online: 19:10
Ah, dat verandert de zaak wel wat (ha, zie je meteen hoe belangrijk het is om een goed voorbeeld van in/output erbij te doen! :) )

Je maakt het wat lastig, als ik je gewenste output zo bekijk, want eigenlijk wil je de eerste CDATA dus juist niet newlinen, enkel weg hebben, en dus alleen tweede en verdere CDATA's wil je dubbel newlinen.

Maar goed - wat dacht je van deze:
code:
1
2
3
4
5
6
7
8
#!/bin/sh

TEST="<[CDATA[regel1<[CDATA[regel2<[CDATA[regel3"

echo "$TEST" |
sed 's@^<\[CDATA\[@@;s@<\[CDATA\[@\
\
@g'

... een oplossing met twee "s" commando's, de eerste doet de een eventuele CDATA aan het begin van een regel verdwijnen, de tweede doet alle CDATA binnen de regel verdwijnen en dubbel newlinen. Output komt in elk geval overeen met wat je wilde.

Ben wel benieuwd of iemand hier nog andere oplossingen voor kan bedenken met sed. Het "a" (append) commando is er denk ik niet zo geschikt voor.

Wel leuk, dit soort uitdagingen. Wist niet eens dat je commando-elementen met "@" kon scheiden, dacht dat het alleen met "/" kon... of dat je substituties met sed ook met newlines kon doen. :)


Edit: met uitroeptekens heb ik trouwens geen problemen in dit script:
code:
1
2
3
4
5
6
7
8
#!/bin/sh

TEST="<![CDATA[regel1<![CDATA[regel2<![CDATA[regel3"

echo "$TEST" |
sed 's@^<!\[CDATA\[@@;s@<!\[CDATA\[@\
\
@g'

... geeft exact dezelfde output als hiervoor.

[ Voor 10% gewijzigd door vanaalten op 12-08-2012 00:18 ]


Acties:
  • 0 Henk 'm!

  • Hero of Time
  • Registratie: Oktober 2004
  • Laatst online: 23:03

Hero of Time

Moderator LNX

There is only one Legend

code:
1
2
3
4
5
6
#!/bin/sh

TEST="<[CDATA[regel1<[CDATA[regel2<[CDATA[regel3"

echo "$TEST" | 
sed 's#<\[CDATA\[#\n\n#g'

Doet precies wat je wilt, met je voorbeeld code iig. Je kan met sed trouwens elk teken gebruiken die je wilt als scheiding. Standaard wordt / gebruikt, maar je kan ook ! ? # @ en wat nog meer gebruiken.
Je vraag hier niets meer wat via trial en error opgelost kan worden.

Commandline FTW | Tweakt met mate


Acties:
  • 0 Henk 'm!

  • JiMiHeNdRiX
  • Registratie: Juni 2008
  • Laatst online: 03-10 08:25
vanaalten schreef op zondag 12 augustus 2012 @ 00:14:

code:
1
2
3
4
5
6
7
8
#!/bin/sh

TEST="<[CDATA[regel1<[CDATA[regel2<[CDATA[regel3"

echo "$TEST" |
sed 's@^<\[CDATA\[@@;s@<\[CDATA\[@\
\
@g'


... een oplossing met twee "s" commando's, de eerste doet de een eventuele CDATA aan het begin van een regel verdwijnen, de tweede doet alle CDATA binnen de regel verdwijnen en dubbel newlinen. Output komt in elk geval overeen met wat je wilde.
Dat is gaaf! Dit is wat ik zocht. Het doet precies wat het moet doen. In Terminal.

<edit> Ik ga even verder experimenteren in Geektool <einde edit>

Hartelijk bedankt voor het meedenken, ben een stap verder gekomen!

[ Voor 22% gewijzigd door JiMiHeNdRiX op 12-08-2012 22:30 ]

Pagina: 1