2012-10-15 1 views
5

Ich möchte einen bestimmten Teil eines übereinstimmenden Ergebnisses als Variable speichern, die später zum Ersetzen verwendet wird. Ich möchte das in einem einzigen Liner behalten, anstatt vorher die Variable zu finden, die ich brauche.Verwenden von Platzhaltern/Variablen in einem sed-Befehl

wenn Apache Konfiguration und Verwendung mod_rewrite können Sie bestimmte Teile von Mustern specificy als Variablen verwendet werden, wie folgt aus:

RewriteRule ^www.example.com/page/(.*)$ http://www.example.com/page.php?page=$1 [R=301,L] 

der Teil der Mustererkennung, die 1 als $ gespeichert ist in der Klammer enthalten ist zur späteren Verwendung. Wenn also die URL www.example.com/page/home wäre, würde sie durch www.example.com/page.php?page=home ersetzt werden. Der "Home" -Teil des Matches wurde also in $ 1 gespeichert, weil es der Teil des Musters innerhalb der Klammer war.

Ich möchte etwas wie diese Funktionalität mit einem sed Befehl, ich muss automatisch viele Zeichenfolgen in einer SQL-Dump-Datei ersetzen, Drop-Tabelle hinzufügen, wenn Befehle vor jeder Tabelle erstellen, aber ich muss den Namen der Tabelle zu tun wissen dies, so dass, wenn die Dump-Datei enthält so etwas wie:

... 
CREATE TABLE `orders` 
... 

ich so etwas ausführen müssen:

:

cat dump.sql | sed "s/CREATE TABLE `(.*)`/DROP TABLE IF EXISTS $1\N CREATE TABLE `$1`/g" 

das Ergebnis zu erhalten

... 
DROP TABLE IF EXISTS `orders` 
CREATE TABLE `orders` 
... 

Ich verwende die Mod_rewrite-Syntax im sed Befehl als ein logisches Beispiel für das, was ich versuche zu tun.

Irgendwelche Vorschläge?

Antwort

8
sed '/CREATE TABLE \([^ ]*\)/ s//DROP TABLE IF EXISTS \1; &/' 

Suchen Sie eine CREATE TABLE-Anweisung, und erfassen Sie den Tabellennamen. Ersetze es durch "DROP TABLE IF EXISTS" und den Tabellennamen, plus ein Semikolon, um die Anweisung zu beenden, und eine Kopie dessen, was verglichen wurde, um die CREATE TABLE-Anweisung beizubehalten.

Dies ist klassische sed Notation. Da Sie bash verwenden, gibt es eine Chance, dass Sie GNU sed verwenden und --posix hinzufügen müssen, um diese Notation zu verwenden, oder Sie müssen das Skript verwenden, um GNUs nicht standardmäßige sed Regexes zu verwenden. Ich habe auch nicht versucht, eine neue Zeile in die Ausgabe einzufügen. Sie können das mit GNU sed machen, wenn es Ihnen wichtig genug ist.

Die wichtigsten Punkte sind die Klammern (klassisch mit einem Backslash maskiert werden müssen) sind der Erfassungsmechanismus und Backslash-Nummer ist der Ersatzmechanismus.

+0

Sie für diese Erklärung danken, es war meine Frage vollständig beantwortet. –

6
sed -r "s/CREATE TABLE (\`.*\`)/DROP TABLE IF EXISTS \1\n &/g" dump.sql 

Test:

kent$ cat t.txt 

CREATE TABLE `orders` 
... 

CREATE TABLE `foo` 
... 
... 

CREATE TABLE `bar` 
... 


kent$ sed -r "s/CREATE TABLE (\`.*\`)/DROP TABLE IF EXISTS \1\n &/g" t.txt 

DROP TABLE IF EXISTS `orders` 
CREATE TABLE `orders` 
... 

DROP TABLE IF EXISTS `foo` 
CREATE TABLE `foo` 
... 
... 

DROP TABLE IF EXISTS `bar` 
CREATE TABLE `bar` 
... 
+0

Danke, das ist ein hervorragendes Beispiel. –