2016-11-22 2 views
0

Ich versuche, ein Skript zu schreiben, die Zeilen aus einer Datei liest enthalten:Ausführen von SQL-Abfragen einer Datei im speziellen Format mit

  • einen Dateinamen eines SQL-Skript, und
  • einige SQL-Abfragen auf demselben Zeile

und startet eine Abfrage.

Es gibt eine list.txt Datei in folgendem Format:

query.sql; set @var:='prod'; 

wo query.sql eine Datei mit SQL-Abfragen, zB:

select * 
    from db 
where [email protected] 

Ich versuche, einen Bash-Skript zu schreiben, das das ausführt Abfragen wie folgt:

mysql -uroot -proot -e 
    "set @var:='prod'; 
    select * 
     from db 
     where [email protected];" 

Hier ist, was ich versucht habe so weit:

while read line; 
    do app=$(echo $line | awk '{for (i=2; i <= NF; i++) printf FS$i; print NL }'; 
    cat `echo $line | awk -F\; '{print $1}'`; echo ";"); 
    mysql -uroot -proot -e "`echo $app`" 
done < list.txt 

Aber ich ein SQL-Fehler habe, weil die Schale nicht gut das * Zeichen in den query.sql entweicht.

mein Code debuggen ich erhalten:

$echo $app 
$set @var:='prod'; select a list.txt mysql query1.sql query.sql from db where [email protected] ; 

Wie kann ich den Code anpassen, um

$echo $app 
$set @var:='prod'; select * from db where [email protected] ; 

haben?

Weitere Details

Es gibt eine loop im awk Befehl, da die Datei list.txt mehrere Abfragen enthalten, zB:

query.sql; set @var:='prod'; @a=asd; @b=zxc, @...=...; 
+0

Mein Fehler, nur die Frage bearbeitet (es war die echte Abfrage, die ich auf dem Server habe) –

+0

@AlessandroBlasetti, möchten Sie die zweite SQL-Anweisung ausführen (nach dem ersten ';'), dann die Anweisungen aus der Datei vor der angegebenen erstes ';', oder? –

+0

@RuslanOsmanov Ich möchte meine letzte Zeile ausführen: 'set @var: = 'prod'; Wählen Sie * aus db wobei system = @ var; ' –

Antwort

2

Ich glaube nicht, dass Sie die SQL lesen müssen Dateien Zeile für Zeile. Unter der Annahme, dass es keine Semikolons in den Dateinamen, können Sie die Abfrage mit dem folgenden Befehl AWK konstruieren:

awk -F\; '{ 
for (i = 2; i <= NF; i++) { 
    if ($i != "") printf("%s;", $i); 
} 
printf("source %s;\n", $1) 
}' list.txt | mysql -uroot -proot 

Der Befehl ; als Feldtrennzeichen verwendet. Die for-Schleife druckt alle Felder ab dem zweiten. Die letzte printf-Funktion erstellt eine Abfrage, die die SQL-Datei bereitstellt.

Die Ursache des Fehlers

Ihr Code schlägt fehl, da dieser Zeile die richtige SQL an den MySQL-Client weitergeben müssen:

mysql -uroot -proot -e "`echo $app`" 

Die Shell interpretiert die Sonderzeichen innerhalb der $app Variable. Insbesondere wird das Zeichen * auf "jede Datei im aktuellen Verzeichnis" erweitert.Um zu verhindern, zu interpretieren, verwenden schwach quoting, das heißt umschließen die Variable in doppelte Anführungszeichen: "$app":

Wenn eine Variable referenzieren, es ist in der Regel ratsam, seinen Namen in doppelte Anführungszeichen einzuschließen. Dies verhindert, dass Umdeutung aller Sonderzeichen innerhalb der Zeichenfolge in Anführungszeichen - außer $, (Backquote) und \ (Escape) ...

Keeping $ als Sonderzeichen in doppelten Anführungszeichen erlaubt Bezugnahme auf eine zitierte Variable ("$variable"), das heißt, die Variable mit seinem Wert ersetzt

auch gibt es keine Notwendigkeit für Subshell Ausdruck (die Backticks und die echo), wenn Sie den Wert der variablen erhalten mögen:

mysql -uroot -proot -e "$app" 
+0

' awk -F \; '{für (i = 2; i <= NF; i ++) {if ($ i! = "") printf ("% s;", $ i);} printf ("Quelle% s; \ n", $ 2 }} 'list.txt ' gibt mir ' setzen @var: =' prod '; source set @var: =' prod '; ' und nicht die' set @var ...; Frage ' –

+0

Ja, Sie haben Recht, ich habe auf eigene Faust modifiziert und es funktioniert! Großartig –

+0

Nur um besser Bash Scripting zu verstehen (ich bin ein Neuling), weißt du, welches Problem in meinem Code war? –

Verwandte Themen