用 bash 中的另一个字符串替换结尾括号

replace ending brackets with another string in bash

我想用另一个字符串替换最后 3 行。使用 sedtr 或其他 bash 解决方案。

给定文件:

{
  [
    {
      text text text
      text text text
      text text text
    }
  ],  
  [
    {
      text text text
      text text text
      text text text
    }
  ]
}

期望的结果:

{
  [
    {
      text text text
      text text text
      text text text
    }
  ],  
  [
    {
      text text text
      text text text
      text text text
bar

我用 sed

试过了
sed -i '' 's/\}\s+\]\s+\}/bar/g' foobar.hcl

尝试过 tr

tr -s 's/\}[:blank:]\][:blank:]\}/bar/g' <foobar.hcl

这可能对你有用 (GNU sed):

sed '1N;:a;N;/^\s*}\s*\n\s*]\s*\n}\s*$/{s//bar/;N;ba};P;D' file

打开 3 行 window 和模式匹配。

使用 perl,您可以使用 -0777 选项将整个输入作为单个字符串读取。如果输入大到 运行 可用内存不足,则不适合。

# this will replace all remaining whitespaces at the end
# with a single newline
perl -0777 -pe 's/\}\s+]\s+\}\s*\z/bar\n/' foobar.hcl

# this will preserve all remaining whitespaces, if any
perl -0777 -pe 's/\}\s+]\s+\}(?=\s*\z)/bar/' foobar.hcl

运行后,您可以使用 perl -i -0777 ... 进行就地编辑。

使用数组 - 假设“text text text”有一些实际的非空格、非标点字符。

mapfile x < file                                # throw into an array
c=${#x[@]}                                      # count the lines
let c--                                         # point c at last index
until [[ "${x[-1]}" =~ [^[:space:][:punct:]] ]] # while last line has no data
do let c--                                      # decrement the last line pointer
   x=( "${x[@]:0:$c}" )                         # reassign array without last line
done
x+=( bar )                                      # add the desired string
echo "${x[@]}" > file                           # write file without unwanted lines

允许任意数量的空白行 &c。即使 }]} 之类的,只要它与数据不在同一行即可。