(очень хороший первый пост!)
Попробуйте это
cat change_env.sh
#!/bin/bash
# spec : change_env.sh <environment> <property> <new value> <file.yml>
case ${#} in [!4] )
echo "usage: change_env.sh <environment> <property> <new value> <file.yml>" 1>&2
exit 1
;;
esac
env="$1" prop="$2" new="$3" file="$4"
bakFile="${file}".bak
mv "$file" "$bakFile"
sed '/^'"${env}"'/,/^[ ]*$/{ # [ spaceChar tabChar ]
/'"${prop}"'/s/\('"${prop}"'\)\(.*$\)/\1'"${new}"'/
}' "$bakFile" > "$file"
редактировать
Обратите внимание, если вы ожидаете, что входные данные будут содержать пробелы в значениях, вы захотите изменить скрипт, чтобы заключить в кавычки все переменные ("$ 1", "$ 2" ...). (Я сделал это сейчас, так как это лучший метод сценариев оболочки).
/env/,/^[{space,tab}]*$/
является адресом диапазона для sed. Он читает блок текста, который содержит настройки вашей среды. Я предполагаю, что ваш пример ввода правильный, и что каждый env отделен пустой строкой. Хм ... это будет последний в файле.
** редактировать **
Спасибо @posdef за указание на некоторые проблемы с этим ответом. Код обновляется для решения конкретного случая.
Даже после исправления я заметил, что при вводе типа
change_env.sh env2 prop2 "new value" file.yml
Соответствующий вывод был
:prop2new value
Таким образом, без жесткого кодирования дополнительных :
и пробелов в подстановке это означает, что вам нужно быть очень многословным в том, как вы называете значение <property>
И <new value>
, т.е.
change_env.sh env2 ":prop2: " "\"new value\"" file.yml
# note extra cruft-^^-----^^^--^^---------^^--------------
соответствующий вывод
env2:
:prop1: "value1"
:prop2: "new value"
:prop3: "value3"
...
:propn: "valuen"
IHTH