У меня есть файл с данными, подобными приведенным ниже. 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"
},
}
}
Я просто хочу заменить значение переменной azure_spoke_gateways
имя
. Желаемый результат:
variable "azure_spoke_gateways" {
default = {
spoke1 = {
name = "MYSTRING"
size = "max"
vpc = "azure_spoke1_vnet"
},
}
}
Вы можете использовать эту команду Perl:
perl -0777 -pe 's/(variable "azure_spoke_gateways".*?name *= *)".*?"/\1"MYSTRING"/gs' input_file
Она заменит все, что находится внутри ""
(не только xyz
) для имени
на MYSTRING
.
Если вы хотите заменить только xyz
, используйте:
perl -0777 -pe 's/(variable "azure_spoke_gateways".*?name *= *)"xyz"/\1"MYSTRING"/gs' input_file
Чтобы изменить input_file
на месте, добавьте -i
флаг прямо перед input_file
.
С sed
:
sed '/^variable "azure_spoke_gateways"\s*{$/ , /^\s*name[^=]*=\s*"[^"]*"$/{
s/\(name[^=]*=\).*/\1 "MYSTRING"/; }' infile
Обычно вы можете анализировать построчно в более простых форматах, пока вы отслеживаете подраздел.
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
Предполагая, что блоки разделены одной или несколькими пустыми строками, вы можете сделать что-то вроде этого с режимом абзаца 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
.