Awk/Sed 命令查找和替换模式

Awk/Sed 命令查找和替换模式

我有一个包含如下数据的文件。xyz可以是任何内容,所以我想替换它。

variable "azure_spoke_gateways" {
  default = {
    spoke1 = {
      name         = "xyz"
      size         = "max"
      vpc          = "azure_spoke1_vnet"
    },
  }
}

variable "google_spoke_gateways" {
  default = {
    spoke1 = {
      name         = "xyz"
      size         = "max"
      vpc          = "azure_spoke1_vnet"
    },
  }
}

我只想替换 的值variable azure_spoke_gatewaysname所需的输出是:

  variable "azure_spoke_gateways" {
      default = {
        spoke1 = {
          name         = "MYSTRING"
          size         = "max"
          vpc          = "azure_spoke1_vnet"
        },
      }
    }

答案1

通常,您可以按照更简单的格式逐行解析,只要您跟踪子部分即可。

awk '  
  match($0,/variable "([^"]+)" {/,m) {  
    v = m[1]  
  }  
  $1 ~ /name/{  
    if(v == "azure_spoke_gateways") {  
      gsub(/"[^"]+"$/, "\"MYSTRING\"", $0)  
    }  
  } 1' data

您也可以将其制作成脚本文件。

#!/usr/bin/awk -f

match($0,/variable "([^"]+)" {/,m) {
    v = m[1]
}
v == "google_spoke_gateways" {
    if($1 == "name"){
        gsub(/"[^"]+"$/, "\"MYSTRING\"", $0)
    }
    if($1 == "size") {
        gsub(/"[^"]+"$/, "\"min\"", $0)
    }
    if($1 == "vpc") {
        gsub(/"[^"]+"$/, "\"google_spoke1_vnet\"", $0)
    }
} 1

然后像这样运行脚本。

awk -f script.awk < data

答案2

假设块由一个或多个空行分隔,你可以用 awk 做这样的事情段落模式

 gawk -vRS= -vmystring='"MYSTRING"' '
   BEGIN {OFS=FS="\n"} 
   $1 ~ /"azure_spoke_gateways"/ {
     for(i=1;i<=NF;i++) {
       if($i ~ /^[[:blank:]]*name[[:blank:]]*=/) sub(/"xyz"/,mystring,$i)
     }
   } {printf $0 RT}
 ' file

如果字段的顺序已知且固定,则可以省去循环来定位字段name

如果您没有 GNU awk (gawk),那么您可以使用常规 awk,但无法利用来RT重新替换实际的记录分隔符 - 您需要将其设置ORS为类似 的固定值\n\n

答案3

sed

sed '/^variable "azure_spoke_gateways"\s*{$/ , /^\s*name[^=]*=\s*"[^"]*"$/{
    s/\(name[^=]*=\).*/\1 "MYSTRING"/; }' infile

答案4

您可以使用以下 Perl 命令:

perl -0777 -pe 's/(variable "azure_spoke_gateways".*?name *= *)".*?"/\1"MYSTRING"/gs' input_file

它将用 替换 里面的任何内容(""不仅仅是xyz)。nameMYSTRING

如果只想替换xyz,请使用:

perl -0777 -pe 's/(variable "azure_spoke_gateways".*?name *= *)"xyz"/\1"MYSTRING"/gs' input_file

若要input_file就地更改,请-i在 之前添加标志input_file

相关内容