Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash:使用sed替换代码块,处理缩进_Bash_Sed - Fatal编程技术网

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"