Toon posts:

[Perl]Volgende regel in WHILE - lus

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hoi Tweakers,

Ik loop met mijn beperkte kennis van Perl tegen het volgende probleem aan:
Ik lees middels een WHILE lus een file, regel voor regel in.
Deze regel wordt geanaliseerd op content.
Als hier een match is, dan moet Perl deze, en de volgende regel, uitvoeren naar een (ander) bestand.

Is er een simpele manier om dit door Perl uit te laten voeren.
Ik heb hieronder een voorbeeld van m'n wens geschreven:

while (<INPUTFILE>)
{
$Regel = $_ ;
if ( $Regel =~ /matchstring/ )
{
print OUTPUTFILE "$Regel" ;
# print hier naar OUTPUTFILE de regel die op $Regel volgt.
}
}

Ik hoop dat mijn vraag duidelijk is.

Ik zit nu met conditionele statements te pielen, maar ik heb zomaar het idee dat het makkelijker moet kunnen.


Alvast bedankt,

YaNewB

[ Voor 3% gewijzigd door Verwijderd op 30-10-2003 14:11 ]


  • zeroxcool
  • Registratie: Januari 2001
  • Laatst online: 14-08 15:59
Het kan aan mij liggen, maar volgens mij is dat al aardig kort/makkelijk. Maar goed, misschien zoiets dan:
Perl:
1
2
3
4
5
while (<INPUTFILE>) {
  if ($_ =~ /matchstring/) {
    print OUTPUTFILE $_;
  }
}

Maar het kan volgens mij nog wel korter...

[ Voor 7% gewijzigd door zeroxcool op 30-10-2003 14:54 ]

zeroxcool.net - curity.eu


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 20-08 00:10
ZeRoXcOoL schreef op 30 oktober 2003 @ 14:53:
Maar het kan volgens mij nog wel korter...
Jep:
Perl:
1
2
3
while (<INPUTFILE>) {
    print OUTPUTFILE if /matchstring/;
}

  • muba
  • Registratie: April 2002
  • Laatst online: 19-10-2013

muba

Prince of Persia!

Je kan het natuurlijk lekker kort maken, maar dat is niet wat de OP vraagt. Ik weet niet hoe groot dat bestand is, maar als het niet vele megabytes betreft, zou ik een soort buffersysteem maken.

Perl:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@bestand = <INPUTFILE>;
close INPUTFILE;
@buffer = @bestand;
      #push @buffer, "";   #lege regel toevoegen aan @buffer
shift @buffer;
#je hebt nu de array @bestand met daarin de hele inhoud van het bestand.
#je hebt een kopie van @bestand genaamd @buffer,
#waar je de eerste regel met shift uit hebt gehaald.
#Die heb je namelijk toch niet nodig.
$teller = -1;
foreach $regel (@bestand) {
  $teller++;
  if ( $regel =~ /matchstring/ ) {
    #print de $regel naar het outputbestand
    print OUTPUTFILE $regel;
    #print de volgende regel uit het inputbestand naar het outputbestand
    print OUTPUTFILE $buffer[$teller];
  }#end if
}#end foreach


Let op: als de laatse regel van het bestand voldoet aan /matchstring/, zal er een range error optreden omdat het script nu probeert een niet-bestaand item uit $buffer te lezen. Eventueel kun je dit opvangen door een leeg item aan @buffer toe te voegen. Om dat te doen moet je uit bovenstaand voorbeeld de ingesprongen regel even uncommenten.

Reporter: Mister Gandhi, what do you think of western civilisation?
Gandhi: I think it would be a good idea


  • muba
  • Registratie: April 2002
  • Laatst online: 19-10-2013

muba

Prince of Persia!

Zeg... is het nou gelukt of niet? :)

Reporter: Mister Gandhi, what do you think of western civilisation?
Gandhi: I think it would be a good idea


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 20-08 00:10
Wat was het nut van die buffer nu? Want volgens mij is het enige wat die doet geheugen opslurpen en dat is juist vreselijk vervelend als je er grote bestanden mee wilt verwerken (wat juist de reden was dat je die buffer wilde toevoegen, zei je?!).

  • muba
  • Registratie: April 2002
  • Laatst online: 19-10-2013

muba

Prince of Persia!

Soultaker schreef op 03 november 2003 @ 20:41:
Wat was het nut van die buffer nu? Want volgens mij is het enige wat die doet geheugen opslurpen en dat is juist vreselijk vervelend als je er grote bestanden mee wilt verwerken (wat juist de reden was dat je die buffer wilde toevoegen, zei je?!).
NEEE!
Wat ik zei was dat dit een kutmethode was als je grote bestanden had, inderdaad vanwege het geheugengebruik.

De buffermethode die ik aandroeg, is alleen handig met niet al te grote bestanden. Wat is het nut ervan? Nou, de OP wou een bestand regel voor regel inlezen en als er een match was, die regel en de volgende regel naar een bestand outputten. Daar is die buffer goed voor. Maar ik bedenk me nu opeens dat het veel efficienter kan.

Perl:
1
2
3
4
5
6
7
while ($inputline = <INPUTFILE>) {
  if ( $inputline =~ /matchstring/ ) {
    print OUTPUTFILE $inputline;
    $nextinputline = <INPUTFILE>;
    print OUTPUTFILE $nextinputline;
  }
}


edit:
Na aanleiding van onderstaande post van Soultaker is de typfout verbeterd.

[ Voor 8% gewijzigd door muba op 04-11-2003 15:12 . Reden: typfout ]

Reporter: Mister Gandhi, what do you think of western civilisation?
Gandhi: I think it would be a good idea


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 20-08 00:10
Ah, dan zijn we het helemaal eens. :) Dit is inderdaad een nette, korte, efficiënte oplossing.

Overigens zit er een typefout in regel 5, maar ok.
Pagina: 1