[AIX 5L 5.3] filteren regels uit groot ASCII bestand

Pagina: 1
Acties:

  • kwiebus
  • Registratie: Oktober 2002
  • Laatst online: 21:55
Ik heb een ASCII bestand van 2183162 regels en wil daar regels uit verwijderen die aan een bepaalde voorwaarde voordoen. Ik dacht dit met een kornshell scriptje te kunnen oplossen.

Het gaat dus om een ASCII bestand met velden gescheiden door een / teken. Ik wil in mijn output alleen die regels zien waarbij veld2 leeg is.

Dit is het scriptje:

code:
1
2
3
4
5
6
7
while read line ; do
 veld1=`echo $line | cut -f1 -d"/"`
 veld2=`echo $line | cut -f2 -d"/"`
 if [[ $veld2 = "" ]] ; then
  echo $veld1 >> outputlijst.txt
 fi
done < inputlijst.txt


Als ik dit scriptje uitvoer dan lijkt het wel te doen wat het moet doen maar loopt ontzettend traag. Een core van de Dual Core 2.1 GHz Power 5+ machine staat dan continu 100% belast en verbruikt enorm veel kernel CPU. De vraag is dus of hetgeen ik wil uitvoeren ook op een snellere/efficiëntere manier uit te voeren valt.

  • Boudewijn
  • Registratie: Februari 2004
  • Niet online

Boudewijn

omdat het kan

greppen met een reg-exp?

Zaram module kopen voor je glasvezelaansluiting?


  • kwiebus
  • Registratie: Oktober 2002
  • Laatst online: 21:55
Volgens is dat niet mogelijk met een grep tenminste ik zou niet weten hoe. Ik heb zelf eens verder gezocht en met awk lijkt het wel te lukken:
code:
1
awk -F/ '$2==""' inputlijst.txt > outputlijst.txt


Volgens mij pakt hij hiermee alle regels met een leeg tweede veld en dit gaat wel razendsnel.

  • Straphka
  • Registratie: Augustus 2002
  • Niet online
zo te zien werkt het al, maar persoonlijk gebrruik ik meestal sed hiervoor.

code:
1
sed -e s/<regexp>//g <fileinput> > <fileoutput>

  • kwiebus
  • Registratie: Oktober 2002
  • Laatst online: 21:55
@Straphka

Met het sed commando wat jij geeft kan je volgens mij iets in een regel zoeken en vervangen. Ik zie dus niet hoe je hetgeen ik wilde bereiken op deze manier met sed kunt uitvoeren. Misschien kan je dat eens verduidelijken?

Verwijderd

kwiebus schreef op zondag 22 juli 2007 @ 12:21:
@Straphka

Met het sed commando wat jij geeft kan je volgens mij iets in een regel zoeken en vervangen. Ik zie dus niet hoe je hetgeen ik wilde bereiken op deze manier met sed kunt uitvoeren. Misschien kan je dat eens verduidelijken?
Je kan een hele hoop meer met sed, je kan o.a. ook regels verwijderen en matchende regels printen.

Ik ken AIX helemaal niet. Maar met de GNU versie van grep kan je bijvoorbeeld het volgende doen.

code:
1
egrep '^[^\/]+\/\/'  inputlijst.txt

  • GX
  • Registratie: Augustus 2000
  • Laatst online: 14-05-2025

GX

Nee.

Dit was wel heel eenvoudig, volgens mij kan dit ook zonder perl-compatible (AIX en grep heb ik nml altijd ruzie mee :P). Hier:

code:
1
2
3
4
5
6
7
8
9
john@gikstop { ~ }$ cat test.txt 
dit/is/een/bestand
waarvan/bij/twee/regels
het//tweede/veld
leeg///is!
Leuk/bedacht/zo/he?
john@gikstop { ~ }$ grep -E '^[^/]+//.*$' ./test.txt
het//tweede/veld
leeg///is!

  • kwiebus
  • Registratie: Oktober 2002
  • Laatst online: 21:55
@flupzor

Jouw egrep commando werkt niet helemaal, maar dat komt denk ik dat niet alle regels in mijn ASCII bestand uit meer dan 1 veld bestaan en // er dus niet in voorkomt:

Hier een voorbeeld ASCII bestand:
code:
1
2
3
4
5
6
7
rij1veld1/rij1veld2/rij1veld3/rij1veld4
rij2veld1/rij2veld2
rij3veld1
rij4veld1/rij4veld2/rij4veld3/rij4veld4
rij5veld1/
rij6veld1/rii6veld2/rij6veld3
rij7veld1


Ik wil dus alleen rij3,rij5 en rij7 te zien krijgen (en eigenlijk rij5 zonder de / erachter), met jouw egrep commando zie je alleen alle rijen waar // in voorkomt en dan volgens mij ook ongeacht waar dit in een rij staat.

Verwijderd

kwiebus schreef op zondag 22 juli 2007 @ 13:32:
@flupzor

Jouw egrep commando werkt niet helemaal, maar dat komt denk ik dat niet alle regels in mijn ASCII bestand uit meer dan 1 veld bestaan en // er dus niet in voorkomt:

..
oh okay, dan had ik het niet helemaal goed begrepen.

zo iets moet wel werken dan.

code:
1
egrep '^[^/]+/?$' inputfile.txt

  • deadinspace
  • Registratie: Juni 2001
  • Laatst online: 13:45

deadinspace

The what goes where now?

kwiebus schreef op zaterdag 21 juli 2007 @ 12:10:
code:
1
2
3
4
5
6
7
while read line ; do
 veld1=`echo $line | cut -f1 -d"/"`
 veld2=`echo $line | cut -f2 -d"/"`
 if [[ $veld2 = "" ]] ; then
  echo $veld1 >> outputlijst.txt
 fi
done < inputlijst.txt
De reden dat het scriptje zo traag is, is omdat je per regel in je file drie keer echo opstart en twee keer cut opstart. Een programma starten is niet de lichtste operatie die er is, en kan zelfs bij kleine programmaatjes als cut en echo makkelijk een paar duizendste seconde kosten. En dat tikt aan als je het een paar miljoen keer moet doen.

Je wil dus liever je script zo maken dat dergelijke programma's één keer starten en vervolgens de hele file in één keer verwerken (zoals de door andere mensen gegeven grep, awk, en sed opdrachten).

(het kan overigens zijn dat echo een shell builtin is, wat de uitvoertijd erg zal verkorten, maar dan blijft nog altijd cut over, en dat zal geen shell builtin zijn)

Verwijderd

deadinspace schreef op zondag 22 juli 2007 @ 17:37:
[...]

De reden dat het scriptje zo traag is, is omdat je per regel in je file drie keer echo opstart en twee keer cut opstart. Een programma starten is niet de lichtste operatie die er is, en kan zelfs bij kleine programmaatjes als cut en echo makkelijk een paar duizendste seconde kosten. En dat tikt aan als je het een paar miljoen keer moet doen.

Je wil dus liever je script zo maken dat dergelijke programma's één keer starten en vervolgens de hele file in één keer verwerken (zoals de door andere mensen gegeven grep, awk, en sed opdrachten).

(het kan overigens zijn dat echo een shell builtin is, wat de uitvoertijd erg zal verkorten, maar dan blijft nog altijd cut over, en dat zal geen shell builtin zijn)
ah okay daarom zijn shell scripts dus soms zo traag.

Dus het volgende had ook nog gekund.

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

IFS='/'
while read veld1 veld2; do
    if [[ $veld2 = "" ]] ; then
        echo $veld1 >> outputlijst.txt
    fi
done < inputlijst.txt

  • kwiebus
  • Registratie: Oktober 2002
  • Laatst online: 21:55
@flupzor

Het scriptje werkt op die manier inderdaad wel snel en doet wat ik wilde bereiken.
Pagina: 1