sed Pattern to Insert Comma after a character

Viewed 1339

Add comma after closing bracket } using bash.

Using

sed 's/variable/&,/g;s/,$//'

adds comma after variable, however,

sed 's/}/&,/g;s/,$//'

doesn't work.

Input:

 variable "policy_name1" {
      description = "abc xyz"
      type        = string
      default = [
        "test1"
        "test2"
      ]
    }
    variable "policy_name2" {
      description = "abc xyz"
      type        = bool
      default     = false
    }

Output:

variable "policy_name1" {
      description = "abc xyz"
      type        = string
      default = [
        "test1"
        "test2"
      ]
    },
    variable "policy_name2" {
      description = "abc xyz"
      type        = bool
      default     = false
    }
2 Answers

Add a comma after curly bracket, but not on last line:

sed -e '$!s/^ \{4\}}$/&,/'
  • $!s/ Not on last line replace
  • ^ \{4\}}$ lines begin with 4 space, followed and terminated by }
  • /&,/ by matched content, followed by ,.

Will render:

    variable "policy_name1" {
    description = "abc xyz"
        type    = array
        default = [
            "test1"
            "test2"
        ]
    },
    variable "policy_name2" {
    description = "abc xyz"
        type        = bool
        default     = false
    },
    variable "policy_name3" {
    description = "simple test string..."
        type        = int
        default     = 42
    }

More complex: Add comma on each lines but not on last for each block:

sed -e ':a;N;/[^{\[(,] *\n/{/\n[ \o11]*[]})]/!s/\n/,\n/};P;D;$!ba'

Could render:

    variable "policy_name1" {
    description = "abc xyz",
        type    = array,
        default = [
            "test1",
            "test2"
        ]
    },
    variable "policy_name2" {
    description = "abc xyz",
        type        = bool,
        default     = false
    },
    variable "policy_name3" {
    description = "simple test string...",
        type        = int,
        default     = 42
    }
  • :a; Label "a" for furthen branch
  • N; Merge with next line
  • /[^{\[(,] *\n/ If buffer contain other than comma or open bracket, followed by newline
  • { then do block:
    • /\n[ \o11]*[]})]/! If NOT buffer contain newline followed by space and other then close bracket
    • s/\n/,\n/ then place a comma before newline
    • }; end of block
  • P; print buffer up to newline
  • D; delete buffer up to newline
  • $!ba If not on last line, branch to "a"

Here is what you can do,

#!/usr/bin/env bash

FILENAME="test.tf"
COUNT=`wc -l $FILENAME | awk '{ print $1 }'`
COUNT=`expr $COUNT - 1`

sed "1,$COUNT s/}/},/" "$FILENAME"

I have provided a bash script so that we can avoid the last line in a right way. This script will append a comma whenever it finds an ending curly bracket ( } ) except for when it is last line.

Related