1

A 有一个包含 SQL 迁移命令的文件。例如

// 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

但我无法填写括号内的内容。

4

4 回答 4

3

这可能对您有用(GNU sed):

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

复制包含 的行createTable,然后附加复制的行和模式匹配并在第一次出现时替换。

于 2016-02-14T10:15:33.480 回答
1

您可以在awk. 将其设置为单引号,您可以在字段 2 中访问所需的值:

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

seds也可以使用:

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

转义单引号有点棘手。或者,您可以用双引号将命令括起来,但是,在这种情况下,您需要注意防止 shell 解释$

sed "s/\\\$this->createTable(\('[^']*'\)/\$this->dropTable(\1);\n\0/"
于 2016-02-14T10:17:16.717 回答
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);
于 2016-02-14T14:45:49.503 回答
1

GNU awk 解决方案:

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

{
    print $0
}

编辑:使用建议,注意这是 GNU awk,并从第一个块 tks 中删除了不需要的打印。

注意:我认为整个 {print $0} 可能会被 '1' (单个字符 '1')替换,但我相信 readable 比 short 更好。

于 2016-02-14T11:34:56.580 回答