Bash:使用sed替换代码块,处理缩进
有一个文件,代码如下所示:Bash:使用sed替换代码块,处理缩进,bash,sed,Bash,Sed,有一个文件,代码如下所示: { "name": { "port": 4466, "host": "localhost", "appPort": 3555, "abc": { "defg": { "host": "localhost", "port": 5500, "userName": "test", "password": "test"
{
"name": {
"port": 4466,
"host": "localhost",
"appPort": 3555,
"abc": {
"defg": {
"host": "localhost",
"port": 5500,
"userName": "test",
"password": "test"
}
},
"name2": {
"port": 4321,
"host": "localhost",
"appPort": 1234,
"abc": {
"defg": {
"host": "localhost",
"port": 5500,
"userName": "test",
"password": "test"
}
},
等等
我需要使用sed(或者awk)替换文件中的以下代码块:
以下是我没有成功的经历:
confSearch='"name": {\n "port": 4466,\n "host": "localhost",\n "appPort": 3555'
confReplacement='"name": {\n "port": 4466,\n "host": "10.20.30.40",\n "appPort": 3555'
sed -i "s|$confSearch|$confReplacement|g" "$configFile"
然后我尝试了以下方法(从“name”搜索到“3555”,然后替换它):
我没有收到任何错误,搜索文本根本没有找到。我想,那是因为缩进。如何正确对待缩进?还是我更喜欢别的?只考虑bash,而不考虑perl
非常感谢您的帮助。看来您只是想更换主机,不是吗?使用类似
sed-i的/“主机”:.*$/“主机”:“10.20.30.40”\n/”
我建议不要将sed用于此任务;JSON不是一种基于行的格式,sed不具备处理它的能力,除非您非常确定文件的格式总是正确的。有一些工具可以正确解析JSON并处理它编码的对象,因此缩进或交换行或在同一行上有多个节点不会让它们感到不安
在这种情况下,我建议jq:
jq 'if .name.port == 4466 and .name.appPort == 3555 and .name.host == "localhost" then .name.host="10.20.30.40" else . end' "$configFile"
假设只有一台主机的端口为4466,在您演示的示例中,您只需要更改ipaddress,为什么要更改整个块?因为在文件中有几行包含“host”,并且行数不是恒定的。我在回答中向您展示了如何使用sed来执行此操作,因为您询问的确切答案是什么?看不到您的答案。我很久以前就删除了我的答案。问题是有几行包含“主机”,并且行数不是恒定的。谢谢。首先尝试了它,它对JSON非常有用,尽管现在不适合我安装smth第三方。因此,它是在另一个地方的JS中实现的,bash脚本现在只调用JS解析器和处理程序来更改值。
sed -i "/name.*/ {N; s/name.*3555\./$confReplacement/g}" "$configFile"
jq 'if .name.port == 4466 and .name.appPort == 3555 and .name.host == "localhost" then .name.host="10.20.30.40" else . end' "$configFile"
sed -i '/"port": 4466,/,/"host": "localhost",/ s/localhost/110.20.30.40/' "$configFile"