2016-02-14 2 views
1

A есть файл, содержащий команды миграции SQL. НапримерИспользование awk или sed добавляет строку на основе соответствия шаблону

// admin_setting 
$this->createTable('{{%admin_setting}}', [ 
    'setting_id' => Schema::TYPE_INTEGER . "(11) NOT NULL AUTO_INCREMENT", 
    'short_description' => Schema::TYPE_STRING . "(255) NOT NULL", 
    'value' => Schema::TYPE_TEXT . " NULL", 
    'PRIMARY KEY (setting_id)', 
], $this->tableOptions); 

// authorization 
$this->createTable('{{%authorization}}', [ 
    'authorization_id' => Schema::TYPE_INTEGER . "(11) NOT NULL AUTO_INCREMENT", 
    'short_description' => Schema::TYPE_STRING . "(255) NULL", 
    'PRIMARY KEY (authorization_id)', 
], $this->tableOptions); 

Я хочу добавить еще одну команду перед строкой, содержащей команду «CreateTable(), так что мой пример файла будет выглядеть следующим образом: -

// admin_setting 
$this->dropTable('{{%admin_setting}}'); 
$this->createTable('{{%admin_setting}}', [ 
    'setting_id' => Schema::TYPE_INTEGER . "(11) NOT NULL AUTO_INCREMENT", 
    'short_description' => Schema::TYPE_STRING . "(255) NOT NULL", 
    'value' => Schema::TYPE_TEXT . " NULL", 
    'PRIMARY KEY (setting_id)', 
], $this->tableOptions); 

// authorization 
$this->dropTable('{{%authorization}}'); 
$this->createTable('{{%authorization}}', [ 
    'authorization_id' => Schema::TYPE_INTEGER . "(11) NOT NULL AUTO_INCREMENT", 
    'short_description' => Schema::TYPE_STRING . "(255) NULL", 
    'PRIMARY KEY (authorization_id)', 
], $this->tableOptions); 

Я вижу много примеров удалить строки, соответствующие шаблону, но никто до сих пор, что не может заставить меня вышеуказанные изменения.

ближайший я пришел в

awk '/createTable/{print "$this->DropTable();"}1' file 

, но я не могу заполнить содержимое внутри скобок.

ответ

3

Это может работать для вас (GNU СЭД):

sed '/createTable/{h;G;s//dropTable/;s/, \[/);/}' file 

Скопируйте строку, содержащую createTable, затем добавить скопированную строку и шаблон матч и заменить на первое вхождение.

+0

Прекрасно подходит для меня. Не могли бы вы потратить время на объяснение параметров h; G. – crafter

+1

@crafter команда 'h' копирует текущую строку в регистр, известный как пространство удержания (HS). Команда 'G' добавляет содержимое HS в пространство шаблонов (PS), которое является регистром, удерживающим текущую строку. См. [Здесь] (http://www.gnu.org/software/sed/manual/sed.html#Other-Commands). – potong

1

Вы можете играть с разделителем полей в awk. Установка его в одинарные кавычки, вы можете получить доступ нужное значение в поле 2:

awk -F"'" '/createTable/{print "$this->dropTable('\''"$2"'\'');"}1' 

СЕПГ s также могут быть использованы:

sed 's/\$this->createTable(\('\''[^'\'']*'\''\)/$this->dropTable(\1);\n\0/' 

Это немного сложнее, чтобы избежать одиночные кавычки. В качестве альтернативы вы можете заключить команду в двойных кавычках, однако, в этом случае вам необходимо позаботиться о предотвращении скорлупы от интерпретирования $:

sed "s/\\\$this->createTable(\('[^']*'\)/\$this->dropTable(\1);\n\0/" 
+0

Ваша первая версия работает для меня. – crafter

+1

Оба должны работать. Они просто отличаются использованием одиночных или двойных кавычек. – hek2mgl

+0

Используйте одиночную кавычку, но вместо того, чтобы прыгать внутрь и из оболочки (это то, что вы делаете, кстати, не избегая одиночных кавычек) просто используйте escape-последовательность '\ 047' везде, где вам нужна одиночная кавычка, например. 'print '$ this-> dropTable (\ 047" $ 2 "\ 047);". В этом случае вы также могли бы использовать 'print '$ this-> dropTable (" FS $ 2 FS ");". –

1

гну AWK решение:

/createTable/ { 
    match ($0, /createTable\('(.*)',/, x) 
    print "$this->dropTable('" x[1] "');" 
} 

{ 
    print $0 
} 

редактировать: использовал предложения, отметив, что это GNU awk, и удалил ненужную печать из первого блока, tks.

примечание: я думаю, что все {print $ 0} можно заменить на «1» (один символ «1»), но я считаю, что читаемый здесь лучше, чем короткий.

+2

Обратите внимание: для этого требуется GNU awk для функции match() с 3 аргументами –

+2

DRY: удалить 'print $ 0; next' из первого блока –

1
$ cat tst.awk 
{ new = $0 } 
sub(/createTable/,"dropTable",new) { 
    sub(/,.*/,");",new) 
    print new 
} 
{ print } 

$ awk -f tst.awk file 
// admin_setting 
$this->dropTable('{{%admin_setting}}'); 
$this->createTable('{{%admin_setting}}', [ 
    'setting_id' => Schema::TYPE_INTEGER . "(11) NOT NULL AUTO_INCREMENT", 
    'short_description' => Schema::TYPE_STRING . "(255) NOT NULL", 
    'value' => Schema::TYPE_TEXT . " NULL", 
    'PRIMARY KEY (setting_id)', 
], $this->tableOptions); 

// authorization 
$this->dropTable('{{%authorization}}'); 
$this->createTable('{{%authorization}}', [ 
    'authorization_id' => Schema::TYPE_INTEGER . "(11) NOT NULL AUTO_INCREMENT", 
    'short_description' => Schema::TYPE_STRING . "(255) NULL", 
    'PRIMARY KEY (authorization_id)', 
], $this->tableOptions); 
Смежные вопросы