Получить несколько значений в файле XML - PullRequest
0 голосов
/ 30 апреля 2018
        <!-- someotherline -->
<add name="core" connectionString="user id=value1;password=value2;Data Source=datasource1.comapany.com;Database=databasename_compny" />

Мне нужно получить значения в ID пользователя, пароле, источнике, базе данных. Не все строки имеют одинаковый формат. Мой желаемый результат будет (имя пользователя = значение1, пароль = значение2, DataSource = datasource1.comapany.com, база данных = databasename_compny)

Это регулярное выражение кажется немного сложнее, поскольку оно сложнее. Пожалуйста, объясните свой ответ, если это возможно.

Я понял, что лучше проходить по каждой строке. Код, который я написал до сих пор

while read p || [[ -n $p ]]; do
  #echo $p
  if [[ $p =~ .*connectionString.* ]]; then
    echo $p
  fi
done <a.config

Теперь внутри, если мне нужно захватить значения.

1 Ответ

0 голосов
/ 30 апреля 2018

Для этого решения я рассматриваю:

  • Некоторые строки могут не содержать данных
  • Без точки с запятой ; находится внутри самих данных (ни имен полей)
  • Нет знака равенства = внутри самих данных (и имен полей)

Возможное решение вашей проблемы:

#!/bin/bash

while read p || [[ -n $p ]]; do

  # 1. Only keep what is between the quotes after connectionString=
  filteredLine=`echo $p | sed -n -e 's/^.*connectionString="\(.\+\)".*$/\1/p'`;

  # 2. Ignore empty lines (that do not contain the expected data)
  if [ -z "$filteredLine" ]; then
    continue;
  fi;

  # 3. split each field on a line
  oneFieldByLine=`echo $filteredLine | sed -e 's/;/\r\n/g'`;

  # 4. For each field
  while IFS= read -r field; do

    # extract field name + field value
    fieldName=`echo $field | sed 's/=.*$//'`;
    fieldValue=`echo $field | sed 's/^[^=]*=//' | sed 's/[\r\n]//'`;

    # do stuff with it
    echo "'$fieldName' => '$fieldValue'";

  done < <(printf '%s\n' "$oneFieldByLine")

done <a.xml

Пояснения

Общий sed Синтаксис замены:

  • sed 's/a/b/' заменит то, что соответствует регулярному выражению a содержимым b
  • Шаг 1

    • -n аргумент говорит sed не выводить, если совпадение не найдено. В этом случае полезно игнорировать бесполезных строк.
    • ^.* - что угодно в начале строки
    • connectionString=" - буквально connectionString = "
    • \(.\+\)" - захват группы в сохранение всего, что находится перед закрывающей цитатой "
    • .*$" - что угодно до конца строки
    • \1 говорит sed заменить целое совпадение только на группу захвата (которая содержит только данные между кавычками)
    • p говорит sed распечатать замену
  • Шаг 3

    • Заменить ; на \r\n; это эквивалентно разделению точкой с запятой, потому что bash может зацикливаться на переносах строк
  • Шаг 4 - имя поля

    • Заменяет литерал = и остальную часть строки ничем (это удаляет его)
  • Шаг 4 - значение поля

    • Заменяет все символы в начале, которые не = ([^=] соответствует всем, кроме того, что находится после символа '^'), до равного символа ничем.
    • Другая команда sed удаляет разрывы строк, заменяя их ничем.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...