从鱼到 bash

Sed from fish to bash

我有一个 providers.tf 包含如下内容:

provider "aws" {
  region = "${var.region}"

  assume_role {
    role_arn = "${var.role_arn}"
  }
}

我需要动态替换 regionrole_arn

对于鱼,下面的表达式可以正常工作

REGION="eu-central-1"
ROLE_ARN="arn:iam:mnsasa:asssasa/codebuild"
sed -i "s/region = \"${var.region}\"/region = \"${REGION}\"/g" providers.tf
sed -i "s/role_arn = \"${var.role_arn}\"/role_arn = \"${ROLE_ARN}\"/g" providers.tf

然而,在bash中,我得到了以下错误

s/region = "${var.region}"/region = "${REGION}"/g: bad substitution

我猜这是因为字符在 /bin/bash 中没有被正确转义。 所以我转义 {$

sed -i "s/region = \"$\{var.region\}\"/region = \"${REGION}\"/g" providers.tf

这给了我

sed -i 's/region = "$\{var.region\}"/region = "eu-central-1"/g' providers.tf
sed: -e expression #1, char 54: Invalid content of \{\}

我是不是还漏掉了一些逃跑的东西?

Ps - 对于 Terraform 用户,我不能在这里使用变量,因为这是不接受动态提供者的 terraform import 命令的前一步。

您可以使用

sed -i 's~\(region = "\)${var\.region}"~'"$REGION"'"~g; s~\(role_arn = "\)${var\.role_arn}"~'"$ROLE_ARN"'"~g' providers.tf

看到 online demo:

#!/bin/bash
s='provider "aws" {
  region = "${var.region}"

  assume_role {
    role_arn = "${var.role_arn}"
  }
}'
REGION="eu-central-1"
ROLE_ARN="arn:iam:mnsasa:asssasa/codebuild"
sed 's~\(region = "\)${var\.region}"~'"$REGION"'"~g; s~\(role_arn = "\)${var\.role_arn}"~'"$ROLE_ARN"'"~g' <<< "$s"

输出:

provider "aws" {
  region = "eu-central-1"

  assume_role {
    role_arn = "arn:iam:mnsasa:asssasa/codebuild"
  }
}

在这两个命令中,变量之前的部分用单引号引起来,变量用双引号引起来,其余部分single-quote引起。

你走得太远了。 Bash.

中只有美元符号$需要转义
"s/region = \"${var.region}\"/region = \"${REGION}\"/g"

我不确定 Fish 有什么区别,因为我不使用它。


顺便说一下,您可以将两个 sed 命令合二为一。

演示:

REGION="eu-central-1"
ROLE_ARN="arn:iam:mnsasa:asssasa"
sed "
    s/region = \"${var.region}\"/region = \"${REGION}\"/g;
    s/role_arn = \"${var.role_arn}\"/role_arn = \"${ROLE_ARN}\"/g
" << 'EOF'
provider "aws" {
  region = "${var.region}"

  assume_role {
    role_arn = "${var.role_arn}"
  }
}
EOF

输出:

provider "aws" {
  region = "eu-central-1"

  assume_role {
    role_arn = "arn:iam:mnsasa:asssasa"
  }
}