получение строки из тегов с использованием sed и grep - PullRequest
0 голосов
/ 04 февраля 2019

ОБНОВЛЕНИЕ 2 Я думаю, мне нужно что-то простое, как это:
Регулярное выражение с отрицательным прогнозом в нескольких строках

получение первого, где оно не предшествуетпо родителю я пробовал это без успеха

((?<![<parent>]))<version>.*

или это, но все же он захватывает все версии:

(?<!^<parent>)<version>(?!<\/parent>)

как получить строку из тегов, используя sed и grep, я пытаюсь захватитьтеги: <groupId>org.test.proj.assent</groupId> <artifactId>mainapp</artifactId> <version>mainapp.1.4</version> <packaging>pom</packaging> <name>main app 1</name>

и затем оттуда, я думаю, я извлеку строку:

<version>mainapp.1.4</version>

я пробовал это:

sed -n '/version/,/version/p' pom.xml | grep -o -e '<version>.*'

но это дает мневсе версии

также я пытаюсь захватить:

sed -n '/\/artifactId/,/\/version/p' pom.xml | grep -o -e '<version>.*'

но все файлы печатаются

 <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" >
    <modelVersion>55.0.0</modelVersion>

    <parent>
        <groupId>org.test.proj</groupId>
        <artifactId>test-invoker</artifactId>
        <version>invoker.0.4</version>
    </parent>

    <groupId>org.test.proj.assent</groupId>
    <artifactId>mainapp</artifactId>
    <version>mainapp.1.4</version>
    <packaging>pom</packaging>
    <name>main app 1</name>

    <properties>
        <app-name>Testing App</app-name>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.prod.db</groupId>
                <artifactId>srver-db</artifactId>
                <version>${project.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    </project>

я могу использовать только собственные инструменты linux без установок

ОБНОВЛЕНО xml и строка для захвата

Ответы [ 3 ]

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

Если доступно Perl, как насчет:

perl -0777 -ne '
    while (m#(<parent>.*</parent>)|(?<=<version>)(.*?)(?=</version>)#sg)
    {print $&, "\n" if $& !~ /(^\$|parent)/}' file.xml

, хотя вы все еще можете чувствовать, что это не просто:).

Объяснение:

  • Опция -0777 указывает perl отбрасывать все строки для включения сопоставления с образцом на нескольких строках.
  • Регулярное выражение сопоставляет оба образца: <parent\>..</parent> и <version>..</version>.Цель первого - пропустить сопоставление с тегом <version> внутри тега <parent>.
  • Наконец, он печатает совпадающую подстроку $&, исключая те, которые начинаются с '$' или содержат 'parent'.
  • Если бы мы могли сказать что-то вроде (?<!<parent>.*)<version>.., как вы упомянули, это было бы намного проще.К сожалению, variable length lookbehind не реализован в Perl (и большинстве других языков) на данный момент.
0 голосов
/ 08 февраля 2019

Вопрос гласит:

я могу использовать только нативные инструменты linux без установок

и используемая версия linux описана в комментарии как:

да, стандартный AWS linux

Я только что проверил, и Amazon Linux поставляется с предустановленной xmllint.

Поэтому решение кажетсябыть:

xmllint --xpath "/*[local-name()='project']/*[local-name()='version']/text()" pom.xml
0 голосов
/ 04 февраля 2019

С GNU awk:

$ awk '/<project/{next} !s && match($0, /<([a-zA-Z]+)>/, tag){s=1} s && ($0~ "</" tag[1] ">"){s=0} !s && match($0, "<version>([^<]*)</version>", ver) {print ver[1]}' file
mainapp.1.4

$ awk '/<project/{next} !s && match($0, /<([a-zA-Z]+)>/, tag){s=1} s && ($0~ "</" tag[1] ">"){s=0} !s && match($0, "<version>([^<]*)</version>", ver) {print ver[0]}' file
<version>mainapp.1.4</version>

Для удобства чтения вставьте несколько строк:

awk '/<project/{next} 
    !s && match($0, /<([a-zA-Z]+)>/, tag){s=1} 
    s && ($0~ "</" tag[1] ">"){s=0} 
    !s && match($0, "<version>([^<]*)</version>", ver) {print ver[1]}' file

Используйте ver[0] для включения самого тега, ver[1] только для внутреннего текста.

Он основан на условии, что все теги root закроются.

...