Unix 명령은 특정 텍스트가 나타날 때까지 위아래로 grep합니다.

Unix 명령은 특정 텍스트가 나타날 때까지 위아래로 grep합니다.

"12345"가 전체 xml의 고유 ID인 다음 예를 고려하십시오.

<Tag 1>
a
b
c
d
12345
x
y
z
</Tag 1>

제공된 ID에 대한 XML 파일을 얻을 수 <Tag 1>있도록 내 파일에서 '12345'를 grep하고 각각 위와 아래로 이동하는 명령이 필요합니다 .</Tag 1>

답변1

XML 인식 파서를 사용하여 XML에서 직접 값을 선택할 수 있습니다. 먼저 XML 조각을 수정하여 유효하게 만들고 다음 위치에 넣습니다 file.xml.

<?xml version="1.0"?>
<Tag_1>
a
b
c
d
12345
x
y
z
</Tag_1>

(1) 요소 이름을 알고 나면 이 명령을 사용하여 값을 선택할 수 있습니다.

xmlstarlet select -t -v '//Tag_1' file.xml

출력(앞의 빈 줄을 포함하여 XML에 따름):

a
b
c
d
12345
x
y
z

요소 태그 이름을 정말로 원하는 경우 다시 추가할 수 있습니다.

xmlstarlet select -t -e Tag_1 -v '//Tag_1' file.xml; echo

두 경우 모두 선택기는 //Tag_1요소의 모든 항목과 일치합니다 Tag_1. 더 정확하게 하려면 XPath 선택기를 사용할 수 있고 사용해야 합니다. 예를 들어, 이 코드 조각은 다음을 stuff사용할 수 있는 옵션을 제공합니다 /root/item/Tag_1.

<root>
    <item><Tag_1>stuff</Tag_1></item>
    <unwanted><Tag_1>nonsense</Tag_1></unwanted>
</root>

(2) 내가 질문을 잘못 읽었고 실제로 원하는 것과 일치하는 요소 이름을 원한다는 사실에 충격을 받았습니다. 이 경우에는더 복잡한 표현그러나 이렇게 하면 원하는 텍스트가 포함된 직접 요소 이름이 제공됩니다 12345.

xmlstarlet select -t -m '//*[contains(text(), "12345")]' -m 'ancestor::*' -b -v 'name()' -n file.xml

산출

Tag_1

필요한 경우 이 솔루션을 사용하여 요소를 식별한 다음 이전 솔루션을 사용하여 해당 데이터를 추출하거나 이 솔루션의 표현을 확장하여 콘텐츠도 포함할 수 있습니다.

xmlstarlet select -T -t -m '//*[contains(text(), "12345")]' -m 'ancestor::*' -b -v 'concat("<", name(), ">", ., "</", name(), ">")' -n file.xml

없는 경우 xmlstarlet표준 패키지이며 설치가 매우 쉽다는 것을 알아야 합니다. 또는 시스템 관리자에게 설치를 요청하세요.

답변2

filename 이 있다고 가정하면 위 의 text.xml검색 문자열에서 데이터를 가져오고 싶습니다.12345

위 내용을 grep

string=`grep -n 12345 text.xml | awk -F: '{print $1}'` && head -n -$(( string - 1 )) text.xml

출력은 다음과 같습니다 -

<Tag 1>
a
b
c
d

다음 콘텐츠를 Grep하세요.

string=`grep -n 12345 text.xml | awk -F: '{print $1}'` && tail -n +$(( string + 1 )) text.xml

출력은 다음과 같습니다 -

12345
x
y
z
</Tag 1>

답변3

사용행복하다(이전 Perl_6)

~$ raku -MXML -e 'my @xml = open-xml($*ARGFILES.Str).getElementsByTagName("tag");  \
                  .put for @xml.grep(/12345/);'  file

Raku의 XML모듈을 사용하여 XML을 구문 분석합니다.

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

입력 예:

<?xml version="1.0"?>
<catalog>
  <tag id="1">
  a
  b
  c
  d
  12345
  x
  y
  z
  </tag>
</catalog>

예제 출력:

<tag id="1">
  a
  b
  c
  d
  12345
  x
  y
  z
  </tag>

contents태그를 제거하고(return ) 선행 공백이 포함된 -acters만 반환 하려면 charRaku에게 이를 제공하도록 요청하세요.linestrim

~$ raku -MXML -e 'my @xml = open-xml($*ARGFILES.Str).getElementsByTagName("tag").map(*.contents);  \
                  .trim-leading.put if .chars for @xml.grep(/12345/).lines;' file 
a
b
c
d
12345
x
y
z

https://raku.org

관련 정보