由于/替换模式,Sed命令失败

时间:2017-09-20 23:22:17

标签: bash sed

我有这个ECS任务定义如下:

{
    ...
    "image": "123.dkr.ecr.us-east-1.amazonaws.com/foo:1.0",
    ...
    "image": "123.dkr.ecr.us-east-1.amazonaws.com/bar:latest",
    ....
}

我只需要更换第一张"图像"值,例如:

{
    ...
    "image": "123.dkr.ecr.us-east-1.amazonaws.com/foo:2.0",
    ...
    "image": "123.dkr.ecr.us-east-1.amazonaws.com/bar:latest",
    ....
} 

这是我的命令sed -e "s/.*foo:.*/\"image\":\"${REPO}:${VERSION}\",/" taskdef.json

REPO=123.dkr.ecr.us-east-1.amazonaws.com/fooVERSION=2.0

的位置

这是我得到的错误:

sed: -e expression #1, char 70: unknown option to `s'

这是因为来自/变量的斜杠REPO

3 个答案:

答案 0 :(得分:2)

你可以使用任何字符作为sed中`s'命令的分隔符,s之后的第一个字符将是分隔符。例如 - #

sed -e "s#foo:.*#\"image\":\"${REPO}:${VERSION}\",#" taskdef.json

将解决此特定问题(假设#$REPO中没有$VERSION),因为/将不再破坏模式。

答案 1 :(得分:0)

要替换第一张图像的值,请执行以下操作:

$ awk -v repo="$REPO" -v vers="$VERSION" '
    !f && ($1~/"image"/) { f=1; sub(/:.*/,""); $0=$0 ": \"" repo ":" vers "\"," } 1
' file
{
    ...
    "image": "123.dkr.ecr.us-east-1.amazonaws.com/foo:2.0",
    ...
    "image": "123.dkr.ecr.us-east-1.amazonaws.com/bar:latest",
    ....
}

如果它们出现在REPO或VERSION中,上面会将转义序列转换为它们的文字字符(例如\t到文字制表符)。这是一个简单的解决方法,如果这是一个可能的问题(只需在命令行上设置它们或导出它们然后使用ENVIRON []访问)并且它将工作,无论字符串中出现什么其他字符,因为它使用文字字符串功能。

答案 2 :(得分:0)

使用json处理器的正确方法称为 jq (v1.5):

示例 ECS 任务定义task.json

{
  "containerDefinitions": [
    {
      "name": "wordpress",
      "links": [
        "mysql"
      ],
      "image": "123.dkr.ecr.us-east-1.amazonaws.com/foo:1.0",
      "essential": true,
      "portMappings": [
        {
          "containerPort": 80,
          "hostPort": 80
        }
      ],
      "memory": 500,
      "cpu": 10
    },
    {
      "environment": [
        {
          "name": "MYSQL_ROOT_PASSWORD",
          "value": "password"
        }
      ],
      "name": "mysql",
      "image": "123.dkr.ecr.us-east-1.amazonaws.com/bar:latest",
      "cpu": 10,
      "memory": 500,
      "essential": true
    }
  ],
  "family": "hello_world"
}

工作:

jq '.containerDefinitions[0].image = (.containerDefinitions[0].image | sub("1.0$";"2.0"))' task.json

输出:

{
  "containerDefinitions": [
    {
      "name": "wordpress",
      "links": [
        "mysql"
      ],
      "image": "123.dkr.ecr.us-east-1.amazonaws.com/foo:2.0",
      "essential": true,
      "portMappings": [
        {
          "containerPort": 80,
          "hostPort": 80
        }
      ],
      "memory": 500,
      "cpu": 10
    },
    {
      "environment": [
        {
          "name": "MYSQL_ROOT_PASSWORD",
          "value": "password"
        }
      ],
      "name": "mysql",
      "image": "123.dkr.ecr.us-east-1.amazonaws.com/bar:latest",
      "cpu": 10,
      "memory": 500,
      "essential": true
    }
  ],
  "family": "hello_world"
}