#awk #yaml #line
Вопрос:
КОНТЕКСТ: Я очень новичок в написании сценариев UNIX и bash
.
У меня есть .bash
сценарий, который принимает .yaml
и массив виртуальных машин, переданных в качестве аргументов.
(например)
myscript.sh my.yaml neo1 neo2 neo3 alice1 alice2 alice3
Как найти шаблон ключа monitor_vm и записать последнюю строку раздела этого монитора и добавить в последние строки этого раздела?
У меня есть один пример функции, которая идентифицирует некоторый шаблон, чтобы указать номер строки этой вставляемой строки ….но это требует некоторых изменений. Пожалуйста, посоветуйте пример
getline() {
awk '
BEGIN { monitor_vms="'${}'"; ln=1; fnd=0; }
(fnd==1 amp;amp; $0 ~ /^ [a-z]/) { exit }
($0~/^monitor_vms:/) { fnd = 1 }
($0 ~ /./ amp;amp; $0 !~ /^#/) { ln = NR }
END { print ln }' ${1}
}
for name in $VM_LIST; do
line=`getline my.yaml monitor_vms`
sed -i -e ${line}"a- name: "${vmname}"n my.yaml
done
Файл my.yaml
выглядит следующим образом:
---
- someotherkey: hello
value: some_value
- someotherkey1: hello1
value1: some_value1
- monitor_vms:
- name: sujana
cnt: 5
- name: vijaya
cnt: 5
- static_configs:
- location:
datacenter:
Я ожидал бы получить требуемое my.yaml
, после обновления:
---
- someotherkey: hello
value: some_value
- someotherkey1: hello1
value1: some_value1
- monitor_vms:
- name: sujana
cnt: 5
- name: vijaya
cnt: 5
- name: neo1
- name: neo2
- name: neo3
- name: alice1
- name: alice2
- name: alice3
- static_configs:
- location:
datacenter:
Комментарии:
1. 🙂 по ошибке. По стандарту это 3 тире . Хороший улов @EdMorton
Ответ №1:
Вам никогда не нужен sed, когда вы используете awk, вы позволяете переменным оболочки расширяться, чтобы стать частью сценариев, и в вашем коде есть другие ошибки оболочки. В качестве отправной точки вам следует скопировать/вставить все ваши сценарии в http://shellcheck.net и исправьте ошибки, о которых он вам рассказывает.
Это использует GNU awk для редактирования «на месте», так как вы использовали GNU sed для того же:
$ cat myscript.sh
#!/usr/bin/env bash
file="$1"
shift
awk -i inplace -v vms="$*" '
/^-/ {
if ( $2 == "monitor_vms:" ) {
inBlock = 1
}
else {
prtVms()
}
}
$1 == "-" {
prev = $0
}
{ print }
END { prtVms() }
function prtVms( vmsArr, i, n) {
if ( inBlock ) {
sub(/:.*/,":",prev)
n = split(vms,vmsArr)
for (i=1; i<=n; i ) {
print prev, vmsArr[i]
}
}
inBlock = 0
}
' "$file"
$ cat my.yaml
---
- someotherkey: hello
value: some_value
- someotherkey1: hello1
value1: some_value1
- monitor_vms:
- name: sujana
cnt: 5
- name: vijaya
cnt: 5
- static_configs:
- location:
datacenter:
$ ./myscript.sh my.yaml neo1 neo2 neo3 alice1 alice2 alice3
$ cat my.yaml
---
- someotherkey: hello
value: some_value
- someotherkey1: hello1
value1: some_value1
- monitor_vms:
- name: sujana
cnt: 5
- name: vijaya
cnt: 5
- name: neo1
- name: neo2
- name: neo3
- name: alice1
- name: alice2
- name: alice3
- static_configs:
- location:
datacenter:
Комментарии:
1. Спасибо тебе, Эд Мортон. Когда я пытался запустить, я получал такую ошибку. Не уверен, что я делаю не так………?? Использование: awk [параметры стиля POSIX или GNU] -файл прогфайла f [ — ]… Использование: awk [параметры стиля POSIX или GNU] [ — ] файл «программа»… Параметры POSIX: длинные параметры GNU: (стандартные) -f файл программы —файл=файл программы-F fs —разделитель полей=fs -v var=val —назначить=var=val Короткие параметры: длинные параметры GNU: ………..
2. Я предполагаю, что вы используете очень старую версию gawk. Что
awk --version
выводит? Если это неGNU Awk 5.1.0
так или новее, установите новую версию gawk, так как ваша устарела. Если вы по какой-то причине не можете этого сделать, просто избавьтесь от этой-i inplace
опции и сделайтеtmp=$(mktemp) amp;amp; awk 'script' file > "$tmp" amp;amp; mv -- "$tmp" file
так, как вы сделали бы с любым инструментом, чтобы перезаписать исходный входной файл выводом инструмента. Это будет работать с любым awk, и это то, что sed, awk, perl, ruby, python и т. Д. Делают в фоновом режиме при вызове с возможностью так называемого редактирования «на месте» в любом случае.