使用sed进行多行替换

时间:2017-12-28 03:00:49

标签: bash sed makefile sequelize.js

由于实用程序中的错误,我需要找到一系列行并更改它们。我一直试图使用sed,但无法弄清楚macOS上的语法。

基本上,我需要找到以下几行:

type: DataTypes.DATE,
allowNull: true,
primaryKey: true

...如果此序列存在,则更改最后两行:

type: DataTypes.DATE,
allowNull: true

整个文件最初看起来像这样:

/* jshint indent: 2 */

module.exports = function(sequelize, DataTypes) {
  return sequelize.define('product', {
    id: {
      type: DataTypes.BIGINT,
      allowNull: false,
      primaryKey: true
    },
    name: {
      type: DataTypes.STRING,
      allowNull: false,
      primaryKey: true
    },
    _u: {
      type: DataTypes.BIGINT,
      allowNull: false,
      references: {
        model: 'user',
        key: 'id'
      }
    },
    _v: {
      type: DataTypes.DATE,
      allowNull: false
    },
    _d: {
      type: DataTypes.DATE,
      allowNull: true,
      primaryKey: true
    }
  }, {
    tableName: 'product'
  });
};

2 个答案:

答案 0 :(得分:2)

对于sed中的多行模式匹配,您需要使用N命令将下一行拉入模式空间。如果我理解你的要求,这样的事情应该是诀窍:

$ cat multiline-replace.sed 
/type: DataTypes.DATE,/{N
    /allowNull: true/{N  
       /primaryKey: true/{
         s/allowNull: true/why would I allow this?/
         s/primaryKey: true/shmimaryKey: false/
       }      
    }
}

我的想法是,当/type: DataTypes.DATE,/匹配时,您会阅读模式空间中的下一行(范围由{}分隔。在allowNull: true行和{{1}上执行相同的操作然后你在模式空间中得到了三行,你可以对它们进行修改。primaryKey: true

我将您的输入复制到文件s/pattern/replacement/中,然后我针对此程序对其进行了测试:

input

另请参阅Unix堆栈交换上的这篇文章,其中提供了有关sed命令的更多详细信息(同时$ cat input | sed -f multiline-replace.sed /* jshint indent: 2 */ module.exports = function(sequelize, DataTypes) { return sequelize.define('product', { id: { type: DataTypes.BIGINT, allowNull: false, primaryKey: true }, name: { type: DataTypes.STRING, allowNull: false, primaryKey: true }, _u: { type: DataTypes.BIGINT, allowNull: false, references: { model: 'user', key: 'id' } }, _v: { type: DataTypes.DATE, allowNull: false }, _d: { type: DataTypes.DATE, why would I allow this?, shmimaryKey: false } }, { tableName: 'product' }); }; $ 是您的朋友):https://unix.stackexchange.com/questions/26284/how-can-i-use-sed-to-replace-a-multi-line-string#26290

答案 1 :(得分:0)

使用sed一段时间后,又不记得语法了,我创建了一个名为file-line-replacer的实用程序,可以一劳永逸地解决该问题。尽管我早在年前就已经选择了“正确”的答案,但出于完整性考虑,我将其发布在这里。这是我使用的步骤。

首先,安装它(我更喜欢在全局安装)...

npm i -g file-line-replacer

...然后,只需运行一个命令(此示例用于上面的续集问题)...

file-line-replacer \
  --search-dir "/Users/flackey/my-project/src/data/models" \
  --backup-dir "/Users/flackey/my-project/_backup" \
  --old-lines "allowNull: false,|primaryKey: true" \
  --new-lines "autoIncrement: true,|primaryKey: true" \
  --overwrite

上面的命令将调整存在旧行的每个文件,并在修改之前创建一个备份。