Regex van SQL statements

Pagina: 1
Acties:

  • Zeezicht
  • Registratie: Juni 2001
  • Laatst online: 01-11 12:35
Uit de logs van mijn SVN repository wil ik een aantal SQL commando's kunnen vissen, die tussen bepaalde revisies horen.
Ik weet dat om de logs te bekijken van revisie 100 tot 110, je het volgende commando geeft:
svn log -r100:111 <url>

Nu wil ik die data pipen door grep heen om zo de commando's eruit te halen.
De insert en update en alter tables zijn niet zo moeilijk, want die beslaan altijd 1 regel. Maar bij een create table statement, zijn het er meer.
Helaas ondersteunt mijn grep geen perl regexp (-P) parameter,want volgens mij kan ik dan meer regelen.

Maar heeft iemand een idee hoe ik dat eruit kan greppen?

VB van een create statement:
code:
1
2
3
4
5
CREATE TABLE `tableName` (
`ID` SMALLINT UNSIGNED NOT NULL ,
`sDescription` TEXT NOT NULL ,
INDEX ( `ID` )
) ENGINE = MYISAM COMMENT = 'Beschrijving';


Met The Regex Coach (programma om makelijk regexen te maken) kom ik ook niet verder, want die wil steeds te 'greedy' matchen. En dat krijg ik niet uit.
Bijvoorbeeld met:
code:
1
CREATE(.*)\((.*);

Gaat grep door met matchen tot de laatste ; ipv de eerste die deze tegenkomt.

  • Trinsec
  • Registratie: Februari 2003
  • Laatst online: 01-12 21:38

Trinsec

Huffi-Muffi-Guffi

Over dat greedy matchen, probeer een ? erachter te plaatsen? (Zoals .*?)

when the Darkness fell upon us
when the Evil Ones came!
Creatures from the darkest pits of hell they were.
Trinsec's Journal


  • Zeezicht
  • Registratie: Juni 2001
  • Laatst online: 01-11 12:35
Trinsec schreef op donderdag 12 april 2007 @ 22:31:
Over dat greedy matchen, probeer een ? erachter te plaatsen? (Zoals .*?)
Dank je wel, dat ik dat zelf niet meer wist.... :(

Maar ja nu dus nog via grep...

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 09:29
Het probleem met grep is dat je altijd regels matcht, en het matchen van patronen over meerdere regels dan eigenlijk onmogelijk is. Ik weet niet of je een exact resultaat nodig hebt, anders kun je misschien de "CREATE TABLE" regel laten matchen en een paar regels erna laten printen (met -A, in mijn versie van grep).

  • Zeezicht
  • Registratie: Juni 2001
  • Laatst online: 01-11 12:35
Probleem met de standaard grep of met de -E optie is dat niet multi-line is. En volgens mij ook anders omgaat met (.*?) delen.

Zijn er nog andere tools voor? Of moet ik me richten op PHP danwel Perl? (Helaas van Perl weinig kaas gegeten).

  • Zeezicht
  • Registratie: Juni 2001
  • Laatst online: 01-11 12:35
Soultaker schreef op donderdag 12 april 2007 @ 23:10:
Het probleem met grep is dat je altijd regels matcht, en het matchen van patronen over meerdere regels dan eigenlijk onmogelijk is. Ik weet niet of je een exact resultaat nodig hebt, anders kun je misschien de "CREATE TABLE" regel laten matchen en een paar regels erna laten printen (met -A, in mijn versie van grep).
Het zou wel het mooiste zijn als ik exacte matches heb, want dan hoef ik dus niet meer te editten in de output. En met een aantal regels erna, moet ik of heel veel nemen, als ik altijd alles wil hebben, of weinig als ik weinig ruis wil ... niet ideaal. Maar ik denk dat er dus weinig anders op zit dan met Perl oid te gaan werken.

Dan moet ik ff gaan zoeken naar het aanroepen van een commando en dat vangen in een variabele en hoe je daar een regex op los laat.

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 09:29
Het is sowieso lastig, want matching braces parsen is ook onmogelijk met reguliere expressies. Maar als je makkelijk het begin en het einde van een statement kunt matchen (bijvoorbeeld gewoon ; als einde zien, en dan maar aannemen dat er geen puntkomma's in je tabeldefinitie voorkomen), kun je het makkelijk met Perl doen:
perl -ne '$x=1 if/CREATE TABLE/; print if $x; $x=0 if/;/'

Het idee is dat je alleen regels print als $x != 0. Als je CREATE TABLE tegen komt zet je die dus op 1, en als je ; tegenkomt weer op 0.

(-e betekent dat je een programma op de command line meegeeft; -n dat de code voor elke regel in de invoer uitgevoerd wordt, in plaats van één keer)

[ Voor 12% gewijzigd door Soultaker op 12-04-2007 23:36 ]


  • Zeezicht
  • Registratie: Juni 2001
  • Laatst online: 01-11 12:35
Soultaker schreef op donderdag 12 april 2007 @ 23:35:
Het is sowieso lastig, want matching braces parsen is ook onmogelijk met reguliere expressies. Maar als je makkelijk het begin en het einde van een statement kunt matchen (bijvoorbeeld gewoon ; als einde zien, en dan maar aannemen dat er geen puntkomma's in je tabeldefinitie voorkomen), kun je het makkelijk met Perl doen:
perl -ne '$x=1 if/CREATE TABLE/; print if $x; $x=0 if/;/'

Het idee is dat je alleen regels print als $x != 0. Als je CREATE TABLE tegen komt zet je die dus op 1, en als je ; tegenkomt weer op 0.

(-e betekent dat je een programma op de command line meegeeft; -n dat de code voor elke regel in de invoer uitgevoerd wordt, in plaats van één keer)
Hartelijk dank!
Ik heb nu naast CREATE TABLE met een OR operator (met | symbool dus) ook INSERT INTO, UPDATE enz. eruit gehaald.

  • sam.vimes
  • Registratie: Januari 2007
  • Laatst online: 08-06 08:44
Alles in een keer:
code:
1
perl -wne 'print if /^(CREATE TABLE|INSERT|ALTER)/../;\s*$/'

In de eerste RE match je het begin van de SQL die je wilt extracten, in de tweede RE (na de ..) match je het einde.

  • Zeezicht
  • Registratie: Juni 2001
  • Laatst online: 01-11 12:35
sam.vimes schreef op vrijdag 13 april 2007 @ 08:47:
Alles in een keer:
code:
1
perl -wne 'print if /^(CREATE TABLE|INSERT|ALTER)/../;\s*$/'

In de eerste RE match je het begin van de SQL die je wilt extracten, in de tweede RE (na de ..) match je het einde.
Bedankt voor deze nogmaals, maar ik had 'm inmiddels zelf al uitgebreid zodat de regex ook die andere deed. Ik zie dat jij alleen ook matched op begin (^) en eind ($). Dat is misschien nog wel een goede toevoegen voor mjn script.
Pagina: 1