Bash 使用sed进行多行替换
由于实用程序中有一个bug,我需要找到一系列行并修改它们。我一直在尝试使用Bash 使用sed进行多行替换,bash,sed,makefile,sequelize.js,Bash,Sed,Makefile,Sequelize.js,由于实用程序中有一个bug,我需要找到一系列行并修改它们。我一直在尝试使用sed,但无法理解macOS上的语法 基本上,我需要找到以下几行: type: DataTypes.DATE, allowNull: true, primaryKey: true 。。。如果存在此序列,则更改最后两行: type: DataTypes.DATE, allowNull: true 整个文件最初看起来如下所示: /* jshint indent: 2 */ module.exports = functio
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'
});
};
对于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
行和primaryKey:true
行上执行相同的操作。然后,在模式空间中有三行,您可以对它们进行修改。s/pattern/replacement/
我将您的输入复制到文件input
中,然后针对该程序对其进行了测试:
$ 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'
});
};
$
另请参阅有关Unix堆栈交换的这篇文章,其中提供了有关sed命令的更多详细信息(还有
mansed
是您的朋友):对于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
行和primaryKey:true
行上执行相同的操作。然后,在模式空间中有三行,您可以对它们进行修改。s/pattern/replacement/
我将您的输入复制到文件input
中,然后针对该程序对其进行了测试:
$ 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'
});
};
$
另请参阅Unix堆栈交换上的这篇文章,其中提供了有关sed命令的更多详细信息(还有
man sed
是您的朋友):在使用sed一段时间后,我再也记不起语法,创建了一个名为的实用程序,以一劳永逸地解决这个问题。尽管我已经选择了“正确的”答:几年前,为了完整起见,我把它贴在这里。以下是我使用的步骤
首先,安装它(我更喜欢全局安装)
npm i-g文件行替换器
…然后,只需运行一个命令(此示例用于上面的sequelize问题)
上面的命令将调整存在旧行的每个文件,并在修改之前创建一个备份。在使用sed一段时间后,我再也记不起语法,创建了一个名为的实用程序,以一次性解决问题。尽管我已经选择了“正确的”答:几年前,为了完整起见,我把它贴在这里。以下是我使用的步骤 首先,安装它(我更喜欢全局安装)
npm i-g文件行替换器
…然后,只需运行一个命令(此示例用于上面的sequelize问题)
上面的命令将调整存在旧行的每个文件,并在修改之前创建一个备份。您需要使用sed还是可以使用其他类似perl的东西,它几乎与正则表达式一样紧凑?在这一点上,我不在乎。我尝试了两种方法都没有成功。我猜我把正则表达式搞砸了。
sed
附带可以用于解决问题的堆栈缓冲区,但一般来说,sed
很难用于多行问题。您需要使用sed还是可以使用其他类似于perl的东西,它对正则表达式几乎同样紧凑?在这一点上,我不在乎。我两种方法都尝试了,但都没有成功。我猜我把正则表达式搞砸了。sed
comes有一个堆栈缓冲区,你可以用它来解决你的问题,但一般来说,sed
很难用于多行问题。你有没有可能在这一个问题上使用你的上帝般的能力…哈哈,我来看看。但是,fwiw,当你在做复杂的多行事情时,升级到一个功能齐全的程序通常比较容易(和高级)编程语言(python或perl).干杯!你完全正确。想一想,我只是在替换一条只会出现一次的线。忘了我说了什么。你仍然是男人。你有没有可能在这条线上使用你的上帝般的力量…哈哈,我来看看。但是,fwiw,当你在做复杂的、多线的事情时,升级到全f通常比较容易eatured(和高级)编程语言(python或perl)。干杯!你完全正确。想想看,我只是在替换一行只会出现一次的代码。忘了我说了什么。你还是那个人。