Bepaalde stukken tekst uit een file halen

Pagina: 1
Acties:

  • doak
  • Registratie: Oktober 2001
  • Niet online
Ik wil van een website die ik heb binnengehaald via wget alleen de stukken hebben die tussen <h3> en <p class="normal"> tags staan. Met grep is dit mogelijk om iig 1 van beide te pakken maar de output is dan verkeerd. Als ik cat templaterip.html | egrep "<h3>" > gestriptefile.html doe dan heb ik wel alle H3 tags maar ik wil ook de bijbehorende tekst die tussen <p class="normal"> </p> tags staan.

Voorbeeld van de inputfile templaterip.html:
<h3>23:10 - <span>test bericht</span></h3>

<p>


<p class="normal">
En hier is het eerste bericht. Deze tekst wil ik ook heben.
</p>
</p>
Zoals jullie zien sluiten die H3 tags wel mooi aan bij de tekst maar is er na de <p class="normal"> een return waar de gewilde tekst staat. Ik hoop het als volgt voor elkaar te krijgen:

<h3>23:10 - <span>test bericht</span></h3>
En hier is het eerste bericht. Deze tekst wil ik ook heben.

Ik heb me rot gezocht maar kan niks vinden dat in de buurt komt. Is er misschien een beter alternatief? laat het me weten.

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 22-01 23:51

NMe

Quia Ego Sic Dico.

cat templaterip.html | egrep "(<h3>.*<\/h3>)|<p class=\"normal\">.*</p>" > gestriptefile.html

Zo misschien?

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

doak schreef op dinsdag 10 juli 2007 @ 05:41:
Ik wil [..] de stukken hebben dit tussen <h3> en <p class="normal"> staan.
[..]
maar ik wil ook de bijbehorende tekst die tussen <p class="normal"> staat.
[..]
[voorbeeld]
De eerse geciteerde zin, de tweede geciteerde zin en het voorbeeld spreken elkaar tegen.

Wie trösten wir uns, die Mörder aller Mörder?


  • zomertje
  • Registratie: Januari 2000
  • Laatst online: 30-01 04:56

zomertje

Barisax knorretje

Misschien kun je met awk iets bereiken?

het ultieme jaargetijde.... | #!/usr/bin/girl | Art prints and fun


  • benoni
  • Registratie: November 2003
  • Niet online
Met grep kun je ook een x aantal regels extra op laten roepen, kijk maar even met 'man grep'.

code:
1
2
3
4
       -A NUM, --after-context=NUM
              Print NUM  lines  of  trailing  context  after  matching  lines.
              Places  a  line  containing  --  between  contiguous  groups  of
              matches.


Als je meteen met de gevonden regels aan de slag wilt gaan, is awk inderdaad geschikter. Daarmee kun je de gevonden '<h3>' regel bijvoorbeeld even opslaan in een variabele, en op het moment dat je de '<p class blah' hebt gevonden een switch omzetten, zolang die switch true is kun je opvolgende regels toevoegen aan je variabele, en als je '</p>' vindt gaat de switch weer op false. Ofzoiets :)

  • doak
  • Registratie: Oktober 2001
  • Niet online
-NMe- schreef op dinsdag 10 juli 2007 @ 05:46:
cat templaterip.html | egrep "(<h3>.*<\/h3>)|<p class=\"normal\">.*</p>" > gestriptefile.html

Zo misschien?
Helaas werkt die niet, krijg niks als output. Al zag die er wel goed leesbaar uit, toch bedankt

Als ik cat templaterip.html | egrep "(<p>.*<\/p>)" doe dan krijg ik deze line terug:
<p>Tekst op 1 line tussen de tags</p> Dit is even anders als de <p class=\"normal\"> om te zien wat het doet. Het blijft dus hangen op de return van een line denk ik. Waar ik aan zat te denken is om het bestand af te zoeken op <p class="normal"> elke return hierna weg te halen en hetzelfde voor het einde van de zin. Dus krijg je <p class="normal">teks tekst</p> en dit valt wel weer te egreppe.

Nog een mogelijkheid. Op deze website heb ik nog wat info gevonden over grep:
Bij het stukje Matching Everthing Until Something gebruiken ze als voorbeeld:
!shortestmatch
<P> [^]* </P>

Weet iemand hoe ik dit dan kan gebruiken want de volgende commando's leveren niks op
grep "(<P>[^]*<\/P>)"
grep: Unmatched [ or [^
grep "(<P>\[^\]*<\/P>)"

Ook sed geprobeerd maar returnd ook niks
sed -n -e 's/.*<p>\([0-9][0-9]*\)<\/p>.*/\1/p' templaterip.html

Bedankt voor de snelle reacties _/-\o_

Verwijderd

Je snapt volgens mij niet helemaal hoe sed en grep werken, en dat is dat ze per lijn werken.

Het voorbeeld van jou, matching everything until something zal dus alleen op een bepaalde regel werken en daarop alles tot iets anders matchen.

Hier is de quick & dirty fix, pipe het door:

code:
1
sed -ne '\#<h3>.*</h3>#p' -e '/<p class="normal">/,\#</p>#p' | egrep -v '</?p[^>]*>'


Grep bekijkt dus elke regel (en sed ook) na elkaar, kijkt of het patroon matcht, en print het dan, of voert een substitutiecommando uit op een losse regel, in het geval van sed.

Jij wilt de regels met <h3> hebben, als die er allemaal zo uitzien als bij jou, dan zullen die allemaal aan het patroon <h3>.*</h3> voldoen.

Wat ik nu doe is zeggen, tegen sed, print niets (-n) en dan de regels die matchen wel laten printen.

Dat doet de expressie '\#<h3>.*</h3>#', deze address-expressie selecteert alle regels die voldoen aan het pattern <h3>.*</h3> en voert dan wat erachter staat uit, namelijk: 'p' (overigens kun je met { } een heel blok commando's gevolgd door ';' erneer zetten).

Hetzelfde geldt voor de volgende expressie, behalve dat deze m.b.v. de ',' een hele range selecteert, namelijk alles wat matcht van <p class="normal"> tot </p>.

Overigens, sed laat je zelf je delimiters kiezen voor zulke strings, 'standaard is / / de regexp delimeter, maar als er / in de expressie zelf voorkomen kun je met \X waarbij X een willekeurig teken is zelf je delimiter kiezen, in mijn geval #.

Als je de regels met '<p...>' en </p> inderdaad niet wilt is het het makkelijkst om nog een keer de boel door egrep -v te halen (zoals ik doe). Het kan ook wel in sed, maar dat is eigenlijk ingewikkelder dan nodig.

Overigens, dit werkt niet correct als je <p>'s genest zijn. Dan stopt het bij de eerste </p> die het tegenkomt.

Wat je had gevonden, over matching until, dat voorbeeld is wat gaar, maar wat de bedoeling is, volgens mij, is om te doen '<p>[^>]*</p>', namelijk, match <p> match dan alles behalve > (dat is wat [^>] betekent, dat is een negated character class, en match dan </p>. Zo voorkom je 'greedy' behaviour, waarbij sed b.v. bij <p> 123 </p> 456 <p> 789 </p> ook het gedeelte met 789 meeneemt. (Maar in jouw geval gaat dit niet goed, omdat je extra span tags erin hebt staan).

[edit2]
Output aangepast naar voorbeeld. (Wel <h3>, niet <p>-tags)

[edit3]
Dit zou ook moeten werken:
cat file.html | sed -n '\#<h3>.*</h3>#p;/<p class="normal">/,\#</p>#{/<p class="normal">/d;\#</p>#d;p;}'

[ Voor 78% gewijzigd door Verwijderd op 10-07-2007 15:22 ]


  • doak
  • Registratie: Oktober 2001
  • Niet online
Hardstikke bedankt voor je voorbeelden en uitleg het werkt idd goed, hier had ik zelf nooi opgekomen. Merk toch wel dat het werken met regular expressions moeilijker is dan gedacht. Ik weet hier nog niet zoveel van af maar wil het zeker leren. In het programma regexbuddy was ik wel al bezig met het maken van expressions alleen werkte mijn creaties niet in linux.

Nogmaals vele dank, ik kan weer verder :)

  • deadinspace
  • Registratie: Juni 2001
  • Laatst online: 01-02 13:45

deadinspace

The what goes where now?

Je kunt ook Ruby gebruiken voor zulk soort dingen; het is een volledige scripting taal met krachtige regexp-mogelijkheden.
code:
1
ruby -e 't = STDIN.read; while t =~ /<p class="normal">(.*?)<\/p>|<h3>(.*?)<\/h3>/m; puts ($1 ? $1 : $2); t = $~.post_match; end' < inputfile

lijkt te doen wat je wil in dit geval. Je kan het natuurlijk ook ombouwen naar een volwaardig script en meteen nog meer processing doen.

Verwijderd

Een groot nadeel van het gebruiken van Ruby, Python en zelfs Perl in zulke omstandigheden, is dat het niet altijd standaard geinstalleerd is... En dan moet je als nog met sed of awk aan de gang. Nu is awk een heel schappelijke taal, daarin is bovenstaand probleem niet echt veel moeite.

In principe kun je in sed overigens alles, er zijn hele sudoku-applicaties in gecode, en ik heb ook wel eens een sed script gemaakt dat een lijst van directories omzette in een HTML-list <ul> <li>, etc, netjes genest, en wat meer, maar dit is niet echt ideaal.

  • smokalot
  • Registratie: Juni 2001
  • Laatst online: 15-01 22:00

smokalot

titel onder

als je t over xhtml hebt zou je nog kunnen proberen met XPath aan de slag te gaan, dat is een taal die specifiek ontworpen is om data uit een xml-tree te halen.

It sounds like it could be either bad hardware or software

Pagina: 1