Home > OS >  Sed from fish to bash
Sed from fish to bash

Time:04-08

I have a providers.tf containing content like:

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

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

I need to replace the region as well as the role_arn dynamically.

With fish, the following expression works fine

REGION="eu-central-1"
ROLE_ARN="arn:iam:mnsasa:asssasa"
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

However, in bash, I got the following error

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

Which I guess is due to character not being correctly escaped in /bin/bash. So I went with escaping { and $

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

Which gives me

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

Am I still missing some escaping here?

Ps - For Terraform people, I can't use variables here, because this is a pre-step of a terraform import commands which does not accept dynamic providers.

CodePudding user response:

You went a step too far. Only the dollar sign $ needs to be escaped in Bash.

"s/region = \"\${var.region}\"/region = \"${REGION}\"/g"

I'm not sure what the difference is with Fish since I don't use it.


By the way, you can combine the two sed commands into one.

Demo:

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

Output:

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

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

CodePudding user response:

You can use

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

See an 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"
s=$(sed 's/\(region = "\)${var.region}"/\1'"$REGION"'"/g' <<< "$s")
sed 's/\(role_arn = "\)${var.role_arn}"/\1'"$ROLE_ARN"'"/g' <<< "$s"

Output:

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

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

In both commands, the part before a variable is quoted with single quotation marks, the variable is quoted with double quotation marks, and the rest is single-quote quoted.

  • Related