두 개의 grep을 하나의 명령으로 결합

두 개의 grep을 하나의 명령으로 결합

다음과 같은 XML이 있습니다.

    <artifactId>myproject</artifactId>
    <version>1.14.0-SNAPSHOT</version>

버전을 추출하고 싶습니다 1.14.0-SNAPSHOT. 즉, 두 개의 grep과 파이프를 사용하여 이 작업을 수행하는 방법을 알고 있습니다.

$ grep -A1 "<artifactId>myproject</artifactId>" pom.xml | grep -Eo "\d+.\d+.\d+-SNAPSHOT"

이 둘을 하나로 결합하려면 어떻게 해야 합니까? 이 작업에 awk나 sed를 사용하는 것이 더 나을까요?

답변1

<version>다음 줄 이후에 확실하다면myproject

sed -n '
    \|<artifactId>myproject</artifactId>|{
        n                                           #get next line
        s|[[:blank:]]*</\?version>[[:blank:]]*||gp  #remove tags and print
    }
' pom.xml

아니면 당신이 가지고 있다면정규식

grep -zoP '<artifactId>myproject</artifactId>\s*\n\s*<version>\K[^<]+' pom.xml

답변2

당신은 코멘트에서 이식 가능한 것을 원한다고 언급했습니다. 정말 훌륭한 일이지만 그렇게 하지 말라고 진심으로 조언합니다. XML상황에 맞는 언어이지만 정규 표현식은 그렇지 않습니다. 정규식은 XML 결과를 올바르게 구문 분석하지 않습니다.

기껏해야 XML이 동일한 형식으로 유지되는 경우에만 작동하는 해킹을 얻을 수 있습니다. 그러나 XML 사양에 따르면 형식은 우연적일 수 있고 동일한 의미를 유지할 수 있습니다. 이는 위험한 가정이며 취약한 코드를 초래할 수 있습니다.

나는 당신이 이것을 하고 싶어하는 이유가 있다는 것을 알고 있습니다. 당신은 이미 방법을 제공하는 답을 가지고 있습니다. 나는 파서가 여전히옳은답변.

그러나 XML 파서를 사용하면 xpath정규식과 매우 유사하지만 계층적 정보를 얻을 수 있습니다.

이 같은:

#!/usr/bin/env perl
use strict;
use warnings;

use XML::Twig;

my $twig = XML::Twig -> parse ( \*DATA );

my $version = $twig -> get_xpath('//item/artifactId[string()="myproject"]/../version',0)->text;
print $version;

__DATA__
<xml>
  <item>
    <artifactId>myproject</artifactId>
    <version>1.14.0-SNAPSHOT</version>
  </item>
</xml>

xpath어떻게 작동하는지 볼 수 있기를 바랍니다 . //item구조 내 어디에서나 항목을 찾습니다. [string()=텍스트 내용을 쿼리합니다. [@someAtt="fish"]속성 확인과 같은 작업을 수행할 수 있습니다 .

그런 다음 ..위로( item) 올라가서 version요소를 가져옵니다. 그런 다음 text값을 얻으십시오 .

개인 여행자로서:

perl -MXML::Twig -0777 -e 'print XML::Twig -> parse ( <> ) -> get_xpath('/item/artifactId[string()="myproject"]/../version',0)->text,"\n"    yourxmlfile.xml

이제는 XML::Twig배우기 더 쉽다고 생각해서 추천합니다. XML::LibXML꽤 좋습니다.

그러나 Windows에서는 Strawberry Perl과 함께 배포되며 많은 패키지 관리자 또는 에서 쉽게 사용할 수 있습니다 CPAN.

아니면 - xmlstarlet당신도 같은 일을 하도록 허용되어야 합니다.

관련 정보