[perl] matching pattern: goed? of niet?

Pagina: 1
Acties:

  • Barreljan
  • Registratie: December 2001
  • Laatst online: 04-09 16:52

Barreljan

...Zoom-Zoom...

Topicstarter
ik heb, nog steeds, een probleempje. Ik heb nou een ietsjes ander iets:

het idee erachter: zoek naar Realtek en ga 2 regels omlaag en kijk of daar subsys in staat. Daarna wou ik het met substr aanpassen omdat hij dus de hele regel neemt (waarin dus Subsys staat).
code:
1
if (/"Ethernet controller"/\n/\n|Subsys/) { ... }

ik haal het uit dit stukje
code:
1
2
3
4
5
6
 170:Realtek         8139h=RTL8139 (A/B/C/8130) Fast Ethernet     Rev=10h
     Class=Ethernet controller
     PCI-INTA -> IRQ 11
     Subsys: Realtek         8139h=RT8139 Fast Ethernet Adapter
     Busmaster=Yes   Mem space=Yes   I/O space=Yes   66MHz=No 
     Node address : 00 02 44 1F 46 AC

Nu was mijn vraag:
Klopt mijn pattern? Zoniet wat doe ik verkeerd en hoe moet het dan?

Time Attacker met de Mazda 323F 2.5 V6 J-spec | PV output


  • Barreljan
  • Registratie: December 2001
  • Laatst online: 04-09 16:52

Barreljan

...Zoom-Zoom...

Topicstarter
*hier stond wat anders*

snert :(

ik wordt een beetje niet goed. Nu d8 ik dat alles goed ging, maar nee. Hij kijkt niet echt naar Ethernet controller, maar naar Subsys
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$f = "90010.txt";
print "$f\n\n";

$string = "Class=Ethernet";

open (FH,$f || die $!);
   while (<FH>) {
       chomp ($_);
     if (/$string \\n \\n |Subsys/) {
       $geknipt = substr($_, 37, 70);
      print "$geknipt\n";
     }
   }
close FH

ik vind alle regels waar subsys in staat
hoe los ik da op? met die /o lukt het me niet

:'( help me. thnx

Time Attacker met de Mazda 323F 2.5 V6 J-spec | PV output


  • tomato
  • Registratie: November 1999
  • Niet online
code:
1
/^ \Q $string \E (?: [^\\n]* \\n ){2} Subsys/x

Zoiets had het kunnen worden, ware het niet dat je met je <> steeds 1 regel leest. Je kunt daarin dus nooit een match vinden over meerdere regels :)


Wat wil je uiteindelijk als output hebben?

  • Barreljan
  • Registratie: December 2001
  • Laatst online: 04-09 16:52

Barreljan

...Zoom-Zoom...

Topicstarter
Op woensdag 03 april 2002 15:31 schreef tomato het volgende:
code:
1
/^ \Q $string \E (?: [^\\n]* \\n ){2} Subsys/x

Zoiets had het kunnen worden, ware het niet dat je met je <> steeds 1 regel leest. Je kunt daarin dus nooit een match vinden over meerdere regels :)


Wat wil je uiteindelijk als output hebben?
mijn output zou moeten worden
RT8139 Fast Ethernet Adapter

nou, het leuke is van mijn stukkie, ik heb nu voor de test 2 verschillende input bestandjes, waarvan 1 hier in staat. Bij de ander krijg je dit als output:

90009.txt

SiS5513 EIDE Ctrl. (A,B step)
SiS900 10/100 Ethernet Adapter
Unknown device
Unknown device
Unknown device
Unknown device

waarvan alle regels die daar staan ook een subsys bevatten. daarom, en ik wil daarvan alleen die SiS900 10/100...

dus wou ik een stukje programeren om "Class=Ethernet controller" te zoeken en dan de eerst volgende regel waar "subsys" in staat een daarvan het nodige uit te halen.
...alleen lukt dat voor geen meter.

snap je het wat?

Time Attacker met de Mazda 323F 2.5 V6 J-spec | PV output


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 09-09 11:02
Misschien zoiets?
code:
1
2
3
4
5
6
7
8
$found=0;
while(<FH>)
{
  if($found)
    { if(($info)=/Subsys:(.+)/) { print "Gevonden: $info!\n"; } }
  else
    { $found=/Class=Ethernet/; }
}

Natuurlijk wel even je regexp aanpassen zodat je echt alleen de informatie krijgt die je wil hebben.

Verwijderd

Als je beslist wil dat die subsys regel 2 eronder staat kan je zoiets als while loopje doen:

(disclaimer: niet getest)
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
my $foundEthernetController = 0;
my $countLines = 0;

while( <FH> )
{
    if( /Ethernet controller/ )
    {
      $foundEthernetController = 1;
      $countLines = 0;
    }

    if( $foundEthernetController )
    {
      if( /Subsys: Realtek/ && countLines == 2 )
      {
        print "Hoera: $0";
      }

      $countLines++;
    }
}

  • Barreljan
  • Registratie: December 2001
  • Laatst online: 04-09 16:52

Barreljan

...Zoom-Zoom...

Topicstarter
Op woensdag 03 april 2002 15:49 schreef Soultaker het volgende:
Misschien zoiets?
code:
1
2
3
4
5
6
7
8
$found=0;
while(<FH>)
{
  if($found)
    { if(($info)=/Subsys:(.+)/) { print "Gevonden: $info!\n"; } }
  else
    { $found=/Class=Ethernet/; }
}

Natuurlijk wel even je regexp aanpassen zodat je echt alleen de informatie krijgt die je wil hebben.
kijk :) ,
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
$f = "90009.txt";
print "$f\n\n";

open (FH,$f || die $!);
$found=0;
while(<FH>)
{
  if($found)
    { if(($info)=/Subsys:(.+)/) { print "Gevonden: $info!\n"; } }
  else
    { $found=/Class=Ethernet/; }
}
close FH

deez werkt goed, maar niet helemaal. Hoe kan ik hem maar 1 keer subsys laten vinden? Als dat lukt ben ik klaar (hoop ik)

Time Attacker met de Mazda 323F 2.5 V6 J-spec | PV output


  • tomato
  • Registratie: November 1999
  • Niet online
Dan gaan we het met deze beschrijving proberen:
Voodoo_man: dus wou ik een stukje programeren om "Class=Ethernet controller" te zoeken en dan de eerst volgende regel waar "subsys" in staat een daarvan het nodige uit te halen.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/perl

use strict;

my $string = 'Class=Ethernet';

open (FH, 'test.txt');

while (<FH>) {
   if (/\Q $string \E/x) {
    1 while ($_ = <FH> xor /Subsys/);
    # Je hebt nu de juiste regel in $_
    # Doe er hier iets mee
    print;
   }
}

close FH;

Dit gaat er wel van uit dat als er ergens 'Class=Ethernet controller' voor komt, er altijd een regel met 'Subsys' op volgt (enige regels later). Om eventuele corrupte bestanden juist te behandelen zou je dat nog iets netter kunnen maken.


[edit]
Overigens vind ik de aanpak van Soultaker wat netter :)

  • Barreljan
  • Registratie: December 2001
  • Laatst online: 04-09 16:52

Barreljan

...Zoom-Zoom...

Topicstarter
nou, die laatste werkt heel mooi, en het maakt niet echt uit of het net is of niet

ik heb hem hier nu zo:
code:
1
2
3
4
5
6
7
8
9
10
11
my $string = 'Class=Ethernet';
open (FH, '90010.txt');
while (<FH>) {
   if (/\Q $string \E/x) {
    1 while ($_ = <FH> xor /Subsys/);
    $knip = substr($_, 37, 70);
      print "$knip\n";
   }
}

close FH;

en het werkt uitstekend!
heel erg bedankt :)

Time Attacker met de Mazda 323F 2.5 V6 J-spec | PV output


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 09-09 11:02
Op woensdag 03 april 2002 16:03 schreef Voodoo_man het volgende:
deez werkt goed, maar niet helemaal. Hoe kan ik hem maar 1 keer subsys laten vinden?
Kwestie van 'last' toevoegen wanneer je 't genoeg geweest vind (na het printen van de eerste gevonden subsys bijvoorbeeld).

  • tomato
  • Registratie: November 1999
  • Niet online
Voodoo_man: en het werkt uitstekend!
heel erg bedankt :)
Ik zou je nog wel willen adviseren om altijd 'use strict;' te gebruiken. Daarvoor zou je in je huidige script alleen $knip nog moeten definieeren.

Ook zou ik altijd -w gebruiken (warnings), of 'use warnings;'. Dan wordt het debuggen al een stuk gemakkelijker :)
Pagina: 1