使用awk或sed根据模式匹配

时间:2016-02-14 09:55:34

标签: awk sed find-replace

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 个答案:

答案 0 :(得分:3)

这可能适合你(GNU sed):

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

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

答案 1 :(得分:1)

您可以在awk中使用字段分隔符。将其设置为单引号,您可以在字段2中访问所需的值:

awk -F"'" '/createTable/{print "$this->dropTable('\''"$2"'\'');"}1'
也可以使用sed' s

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

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

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

答案 2 :(得分:1)

GNU awk解决方案:

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

{
    print $0
}

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

注意:我认为整个{print $ 0}可以替换为' 1' (单个字符' 1'),但我相信这里的可读性比短片好。

答案 3 :(得分: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);