Поиск и замена строкового значения в YAML на формат с использованием Shell - PullRequest
0 голосов
/ 09 февраля 2019

У меня есть YAML найти и заменить значение в правильном формате YAML (с пробелом и кавычки).Ниже пример YAML, я могу заменить значение jdbcUrl, используя команду Sed ниже.Но, нужна помощь, как префикс пробела и кавычки значения с помощью Sed.Ниже Sed найдет и заменит требуемый jdbcUrl.Но он не будет ставить перед пробелом (стандарт YAML) и добавлять кавычки значения.

Скрипт для поиска и замены URL:

DB_URL='jdbc:mysql://localhost:3306/sd?autoReconnect=true'
sed -i -e 's, MYDATABASE,'$DB_URL',g' input.yaml

Пример ввода Yaml:

- name: AP_DB
      description: "datasource"
      jndiConfig:
        name: jdbc/AP_DB
      definition:
        type: RDBMS
        configuration:
          jdbcUrl: MYDATABASE
          username: username
          password: password
          driverClassName: com.mysql.jdbc.Driver

Требуемый выход Yaml:

- name: AP_DB
      description: "datasource"
      jndiConfig:
        name: jdbc/AP_DB
      definition:
        type: RDBMS
        configuration:
          jdbcUrl: 'jdbc:mysql://localhost:3306/sd?autoReconnect=true'
          username: username
          password: password
          driverClassName: com.mysql.jdbc.Driver

1 Ответ

0 голосов
/ 10 февраля 2019

У вас, похоже, есть несколько заблуждений, которые, кажется, мешают вам решить эту проблему:

  • Ваш входной файл недействителен YAML, и замена MYDATABASE не собирается это исправить.Вы не можете иметь скалярное значение для name и отображения (начиная с клавиши description) одновременно.Я предполагаю, что ваш файл должен выглядеть следующим образом:

    - name: AP_DB
      description: "datasource"
      jndiConfig:
        name: jdbc/AP_DB
      definition:
        type: RDBMS
        configuration:
          jdbcUrl: MYDATABASE
          username: username
          password: password
          driverClassName: com.mysql.jdbc.Driver
    
  • Добавление кавычек к значению, присвоенному DB_URL в оболочке, не имеет значения

  • вы используете не оболочку, а sed для внесения изменений.Ваша оболочка просто используется для вызова sed
  • Вы вызываете sed с помощью -i, который перезаписывает ваш input.yaml, что затрудняет проверку правильности вывода, и вам нужноназад ваши изменения
  • Пробел не является префиксом, это пробел, который обычно должен следовать за индикатором значения YAML (:)
  • Вы соответствуете этому пробелу в своем шаблоне, но выего нет в шаблоне замещения, и в шаблоне замещения нет кавычек.Вы, вероятно, думаете, что есть окружающие $DB_URL, но, конечно, это не так.
  • Кавычки вокруг URL в вашем выводе излишни

Если вы действительно хотите вывод, как выуказать есть несколько вариантов.Прежде всего, вы можете просто изменить соответствующую строку в YAML, чтобы включить кавычки

      jdbcUrl: 'MYDATABASE'

, и немного изменить команду sed:

sed -e 's,MYDATABASE,'$DB_URL',g' < input.yaml

Если вы не можете изменить input.yaml, вы можете просто добавить кавычки (и пробел) в подстановку sed:

sed -e 's, MYDATABASE, "'$DB_URL'",g' < input.yaml

Или не использовать одинарные кавычки и конкатенировать префикс и постфикс к $DB_URL, но использовать двойные кавычки,которые позволяют расширять $DB_URL:

sed -e "s, MYDATABASE, '$DB_URL',g" < input.yaml

Как только вы убедитесь, что любое из этих решений работает, вы можете повторно добавить опцию замены на месте -i в sed.


sed не подходит для этого, особенно потому, что вы, кажется, незнакомы с ним и с YAML.Используйте правильный YAML-парсер, чтобы делать подобные вещи.Они имеют тенденцию продолжать работать, когда простое сопоставление с образцом больше не выполняет свою работу.И механизм сброса анализатора знает, когда вставлять кавычки, а не вставлять их тупо, когда они не нужны.Синтаксический анализатор также будет указывать, что ваш ввод недопустим YAML с самого начала.

Это немного больше кода для этого, например, в Python, но, по крайней мере, он соответствует только значениям отображения, которые в точности соответствуют вашей строке замещения, ине пытается делать замены для ключей, элементов последовательности, в комментариях YAML или для сопоставления значений, таких как ORIG_MYDATABASE, если они находятся в файле.Предотвратить это с помощью sed может быть довольно сложной задачей.

Такая программа на Python может выглядеть как subst.py:

import sys
from pathlib import Path
from ruamel.yaml import YAML

val = sys.argv[1]
subst = sys.argv[2]
file_name = Path(sys.argv[3])

def update(d, val, sub):
    if isinstance(d, dict):
        for k in d:
            v = d[k]
            if v == val:
                d[k] = sub
            else:
                update(v, val, sub)
    elif isinstance(d, list):
        for item in d:
            update(item, val, sub)

yaml = YAML()
yaml.preserve_quotes = True  # to preserve superfluous quotes in the input
data = yaml.load(file_name)
update(data, val, subst)
yaml.dump(data, file_name)

и вызываться из оболочки, как sed должно быть, используя:

python subst.py MYDATABASE $DB_URL input.yaml

Конечно, в выводе вокруг URL не будет кавычек, так как они излишни и не во входном файле, а излишние кавычки вокруг datasource сохранились.

...