Home > database >  How to replace a word in a specific line where the replace pattern contains a variable?
How to replace a word in a specific line where the replace pattern contains a variable?

Time:12-08

I have the following files:

[root@f9044b5d9d1e aws-marketing-and-sales]# grep -HRe ".*\/common\/.*\${local.parent_folder_name}" *
ap-northeast-1/config/config/terragrunt.hcl:  inline_policy = templatefile("${get_parent_terragrunt_dir()}/common/${local.environment}/config/${local.parent_folder_name}/inline-policy-s3.tpl", {
ap-northeast-2/config/config/terragrunt.hcl:  inline_policy = templatefile("${get_parent_terragrunt_dir()}/common/${local.environment}/config/${local.parent_folder_name}/inline-policy-s3.tpl", {
ap-south-1/config/config/terragrunt.hcl:  inline_policy = templatefile("${get_parent_terragrunt_dir()}/common/${local.environment}/config/${local.parent_folder_name}/inline-policy-s3.tpl", {
ap-southeast-1/config/config/terragrunt.hcl:  inline_policy = templatefile("${get_parent_terragrunt_dir()}/common/${local.environment}/config/${local.parent_folder_name}/inline-policy-s3.tpl", {

I'm trying to replace the occurrences of "${local.parent_folder_name}" where the line contains "common" in all files with the parent folder name, like this:

for file in $(grep -HRe ".*\/common\/.*\${local.parent_folder_name}" *); do
  filename=$(echo $file | cut -d: -f1)
  parent=$(echo $file | rev | cut -d/ -f2 | rev)
  sed -i "/common/\${local.parent_folder_name}/$parent/g" $filename
done

This is the error that I get when running the above script:

sed: -e expression #1, char 9: unknown command: `$'

I've found some SO questions regarding this but none of them have examples with using a variable as the replace pattern.

I've also tried different separators (| , !) but to no avail.

Edit: @moshe, it didn't work, that's the output:

grep -Re "/common\/.*\${local.parent_folder_name}" . | while read -r grep_line; do
  if [[ $grep_line == *"$0"* ]]; then
    continue
  fi
  echo $grep_line
  filename=$(echo $grep_line | cut -d: -f1)
  parent=$(echo $grep_line | rev | cut -d/ -f2 | rev)
  echo "parent: $parent"
  sed -i "/common/s?\${local.parent_folder_name}?$parent?g" $filename
done
./ca-central-1/config/config/terragrunt.hcl:  inline_policy = templatefile("${get_parent_terragrunt_dir()}/common/${local.environment}/config/${local.parent_folder_name}/inline-policy-s3.tpl", {
parent: ${local.parent_folder_name}
sed: 1: "./ca-central-1/config/c ...": invalid command code .
./us-west-2/config/config/terragrunt.hcl:  inline_policy = templatefile("${get_parent_terragrunt_dir()}/common/${local.environment}/config/${local.parent_folder_name}/inline-policy-s3.tpl", {

What am I doing wrong?

CodePudding user response:

not sure what the parent var should be, probably should fix it, but the script could look like that

#!/bin/bash
grep -re "/common\/.*\${local.parent_folder_name}" . | while read -r grep_line; do
  if [[ $grep_line == *"$0"* ]]; then
    continue
  fi
  echo $grep_line
  filename=$(echo $grep_line | cut -d: -f1)
  parent=$(echo $grep_line | rev | cut -d/ -f2 | rev)
  echo "parent: $parent"
  sed -i "/common/s?\${local.parent_folder_name}?$parent?g" $filename
done

Note that sed takes a pattern (/common/) and then a command (a to append, d to delete, s to replace)

We want to change only lines with the pattern /common/ in them, so after the pattern, we perform a regular search and replace - s/\${local.parent_folder_name}/$parent/g

To make it more readable, I changed the separator / to ?

So the sed is:

sed -i "/common/s?\${local.parent_folder_name}?$parent?g" $filename
  • Related