我有一个包含如下数据的文件。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_gateways
。name
所需的输出是:
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
)。name
MYSTRING
如果只想替换xyz
,请使用:
perl -0777 -pe 's/(variable "azure_spoke_gateways".*?name *= *)"xyz"/\1"MYSTRING"/gs' input_file
若要input_file
就地更改,请-i
在 之前添加标志input_file
。