Как извлечь часть значения тега XML в сценарии Bash

Добавьте параметры хоста в ваш файл ~/.ssh/config(начните с пустого файла, если он еще не существует )вот так:

Host host.somewhere.dk
  Hostname host.somewhere.dk
  KexAlgorithms diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1
  IdentityFile ~/.ssh/private.key
  Ciphers aes256-cbc
  HostKeyAlgorithms ssh-dss
  Port 10022
  User user

При необходимости, если вы не хотите использовать файл конфигурации, запишите параметры хоста в командную строку.:

ssh -oHostKeyAlgorithms=ssh-dss -oKexAlgorithms=diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1 -oCiphers=aes256-cbc -i ~/ssh/private.key -p 10022 user@host

Также обратите внимание, что в обоих случаях номера портов выше 1024 считаются небезопасными для системных служб, поскольку любой (непривилегированный -пользователь )может открыть порт с таким высоким номером. Лучше использовать более низкий, привилегированный порт.

0
14.09.2021, 09:16
3 ответа

Вы также можете извлечь это имя с помощьюgrep(опция -Eпозволяет использовать расширенные регулярные выражения):

runNumber=$(grep -Eo '[[:alnum:]]+-[[:alnum:]]+' A.xml | cut -d- -f2)

Если вы хотите убедиться в правильности строки этого тега, вы можете предварительно -отфильтровать ее с помощью другой grepкоманды:

runNumber=$(
  grep '<ExperimentName>' A.xml \
  | grep -Eo '[[:alnum:]]+-[[:alnum:]]+' \
  | cut -d- -f2
)

ПРИМЕЧАНИЕ:

Решения на основе выражений XPath -:

  • более читабельны
  • может быть гораздо более отказоустойчивым
  • но они могут вводить некоторые дополнительные зависимости
-1
14.09.2021, 10:07

Использование толькоxmlstarlet:

experiment_name=$(
    xmlstarlet sel -t \
        -m '/RunParameters/ExperimentName' \
        -v 'substring-before(substring-after(., "-"), "-")' file.xml
)

Это соответствует интересующему нас узлу, а затем удаляет среднюю часть значения этого узла с помощью двух функций substring-after()и subsring-before().

Затем выход xmlstarletприсваивается переменной experiment_name.

В качестве альтернативы, используя xqизhttps://kislyuk.github.io/yq/

experiment_name=$(
    xq -r '.RunParameters.ExperimentName | split("-")[1]' file.xml
)

Это просто разбивает значение узла на тире и возвращает второй элемент результирующего массива.

1
14.09.2021, 22:03

Использование Raku (, ранее известного как Perl _6)

raku -MXML -e 'for open-xml($*ARGFILES) {.elements(:TAG<ExperimentName>)>>.contents.put};' < input.xml

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

<?xml version="1.0"?>
<RunParameters xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <RunParametersVersion>NextSeq_4_0_0</RunParametersVersion>
  <ReagentKitSerialWasEnteredInBaseSpace>false</ReagentKitSerialWasEnteredInBaseSpace>
  <ExperimentName>210913-RUN61-COCO</ExperimentName>
  <PurgeConsumables>false</PurgeConsumables>
  <MaxCyclesSupportedByReagentKit>92</MaxCyclesSupportedByReagentKit>
  <ModuleName />
  <ModuleVersion />
</RunParameters>

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

210913-RUN61-COCO

Как уже упоминалось, вы наверняка захотите использовать специальный анализатор XML для этой задачи. Вкратце, для приведенного выше кода Raku вызывается в командной строке bash, а модуль -MXMLзагружается с помощью команды -MXML. Обратите внимание, что приведенный выше код основан на перенаправлении оболочки <[без перенаправления вы должны преобразовать ввод open-xml()в $*ARGFILES.Str]. Файл xml открывается с помощью open-xmlи запрашивается желаемое TAG, contentsизвлекается и возвращается с помощью put.

На самом деле, OP предоставил совершенно хороший код, используя cutдля извлечения RUN61части вывода, и приведенное выше решение Raku можно просто передать через код OP. Однако для полного решения Raku -просто вставьте вызов .split("-")[1]между .containsи .putв приведенном выше коде Raku :

.
raku -MXML -e 'for open-xml($*ARGFILES.Str) {.elements(:TAG<ExperimentName>)>>.contents.split("-")[1].put};'

https://github.com/raku-community-modules/XML
https://www.raku.org

0
15.09.2021, 03:44

Теги

Похожие вопросы