[grep in shell script] stupid user error?

Pagina: 1
Acties:

  • 0siris
  • Registratie: Augustus 2000
  • Laatst online: 21:56
naar aanleiding van een vorig topic van mij even het volgende:
Ik probeer in een string, gescheiden door pipe-tekens (|) bepaalde regels er uit te halen.
In het vorig topic wilde ik uit een bestand een regel halen als in de 6e kolom het getal 06

stond. Dat leverde dit op:
code:
1
grep -E "^(\w+\|){6}03\|" bronbestand


Nu ga ik een stapje verder: in een bestand vol met regels zoals onderstaande, probeer ik voor

elkaar te krijgen dat alle regels waar in de vierde kolom het getal 01 staat, alsmede de 6e

kolom het getal 03,04,05 of 06 bevat, er uit te filteren.
Dus een regel als deze:
code:
1
009 01|0576|2445|01|200403171334|00|06|000000+|etc.etc.etc.

zou er door dit fraaie grepwerk uitgehaald moeten worden:
code:
1
/usr/linux/bin/grep -E "^(.+\|){3}01\|(.+\|){2}(03|04|05|06)\|" bronbestand

Maar dat werkt niet.
Dat greppen zou volgens mij dit moeten doen:
kijk vanaf het begin van de regel tot je een | teken tegenkomt, dat 3x en kijk of daar 01 staat. Kijk vervolgens 2x een | teken verder of daar 03, 04, 05 of 06 staat, gevolgd door een | teken.

zelfs als ik alleen het eerste stuk van dat grepcommando geef en kijk wat er in de 4e kolom staat:
code:
1
/usr/linux/bin/grep -E "^(.+\|){3}01\|" bronbestand | cut -d"|" -f4

staan er allerlei getallen, niet alleen 01!

Ik doe mijn best, maar snap nu toch echt even niet meer waar ik aan toe ben....
Dus plz geen antwoord als RTFM, man bash en dat soort dingen roepen :X

ach...in een volgend leven lach je er om!


  • ajvdvegt
  • Registratie: Maart 2000
  • Laatst online: 04-12-2025
Je zit hier natuurlijk niet op te wachten, maar bij mij werkt je script gewoon. Ik heb even deze test data aangemaakt:
code:
1
2
3
4
5
6
7
009 01|0576|2445|01|200403171334|00|01|000000+|
009 02|0576|2445|02|200403171334|00|02|000000+|
009 03|0576|2445|03|200403171334|00|03|000000+|
009 04|0576|2445|01|200403171334|00|04|000000+|
009 05|0576|2445|02|200403171334|00|05|000000+|
009 06|0576|2445|01|200403171334|00|06|000000+|
009 07|0576|2445|02|200403171334|00|07|000000+|

De uitvoer van
grep -E "^(.*\|){3}01\|(.+\|){2}(04|06)\|.*" test.data
is
code:
1
2
009 04|0576|2445|01|200403171334|00|04|000000+|
009 06|0576|2445|01|200403171334|00|06|000000+|

Ook als ik die cut opdracht toevoeg is de uitvoer zoals verwacht.

Dit alles is op Debian GNU/Linux unstable. Welk systeem heb jij? En wat geeft mijn test invoer als uitvoer bij jou?

I don't kill flies, but I like to mess with their minds. I hold them above globes. They freak out and yell "Whooa, I'm *way* too high." -- Bruce Baum


  • 0siris
  • Registratie: Augustus 2000
  • Laatst online: 21:56
pffff.... nou ik ben blij te horen dat ik niet gek aan het worden ben ;)
het draait op een machine op mijn werk, een IBM met AIX 5.2.
Ik heb daar ook een linux machine (Debian stable), ga daar morgen eens verder mee.

OK, ik kan mijn verwarring terugbrengen tot het volgende:
code:
1
2
grep -E "^(.*\|){5}47\|.*" bronbestand
009 01|0576|2433|01|200403171310|47|00|000000+|000000000+|

dat gaat dus goed
code:
1
2
grep -E "^(.*\|){5}04\|.*" bronbestand
009 01|0576|2440|01|200403171320|11|04|000001+|000000100+|

dat gaat dus fout! En ik denk dat als ik DAT snap, ik er wel ben ;)

[ Voor 98% gewijzigd door 0siris op 26-03-2004 11:05 . Reden: update met meer detail ]

ach...in een volgend leven lach je er om!


  • 0siris
  • Registratie: Augustus 2000
  • Laatst online: 21:56
*schop*

ach...in een volgend leven lach je er om!


  • Spider.007
  • Registratie: December 2000
  • Niet online

Spider.007

* Tetragrammaton

Ik snap niet waarom je het script van ajvdvegt niet kunt gebruiken? Wat is er fout aan
code:
1
2
grep -E "^(.*\|){5}04\|.*" bronbestand
009 01|0576|2440|01|200403171320|11|04|000001+|000000100+
:?

---
Prozium - The great nepenthe. Opiate of our masses. Glue of our great society. Salve and salvation, it has delivered us from pathos, from sorrow, the deepest chasms of melancholy and hate


  • ajvdvegt
  • Registratie: Maart 2000
  • Laatst online: 04-12-2025
De 'fout' is dat '04' in de 7de kolom staat, niet in de 6de.

Dat komt doordat '.*' gewoon alle eventuele extra kolommmen matcht: je zoek immers slechts op de getal/kolom vooraf gegaan door een minimaal aantal kolommen (beetje vage omschrijving, ik hoop dat het duidelijker wordt - regexpen zijn een taal op zich en m.i. niet bedoeld om woordelijk te worden uitgelegd :)). Je specificeert niet (hoewel je dat wel probeerd met de {}'s.) hoeveel er voor MOGEN staan: je specificeert een minimum, geen maximum.

Als je dit gebruikt werkt het wel:
code:
1
grep -E "^([^\|]*\|){5}00\|.*" test.data

Dus ipv een puntje voor 'welk karakter dan ook', moet je daar 'alles behalve een |' van maken (bovenstaande code werkt wederom bij mij). Alleen ben ik nu even kwijt welke kolom het je nu precies om gaat, dus dat getal moet je zelf even invullen :)

[ Voor 44% gewijzigd door ajvdvegt op 26-03-2004 15:51 ]

I don't kill flies, but I like to mess with their minds. I hold them above globes. They freak out and yell "Whooa, I'm *way* too high." -- Bruce Baum


  • 0siris
  • Registratie: Augustus 2000
  • Laatst online: 21:56
ik ben nog ver van een Jedigrep-master, maar het werkt, en ik snap het ook nog, en ik heb het nu gecombineerd tot:
code:
1
grep -E "^([^\|]*\|){3}01\|([^\|]*\|){1}(03|04|05|06)\|" bronbestand

ajvdvegt: Als je een mooie meid was, kreeg je een zoen. Maar jah.... :*)
Thanks!!

ach...in een volgend leven lach je er om!

Pagina: 1