Linux에서 grep 또는 awk를 사용하여 xml의 문자열에서 값을 추출하는 방법

Linux에서 grep 또는 awk를 사용하여 xml의 문자열에서 값을 추출하는 방법

다음을 포함하는 파일이 있습니다.

DEVICE="7" PGMNR="24" VCONF="800"

이 파일 에서 PGMNR="24"."

PGMNR="24"행의 어느 위치에나 있을 수 있습니다 . 줄의 시작, 중간 또는 끝입니다.

이 값을 얻는 방법을 모르겠습니다.

주석의 XML 예:

<?xml version="1.0" encoding="utf-8"?>
<NT3Config>
  <System
      Dev="7"
      PGMNR="24"
      VCONF="800 800"
  />
  <WA-NT
      info="23 1 1 1 61 17 00"
      name="Soja T#1"
  />
  <WA-NT
      info="23 2 2 1 61 17 00"
      name="MatadorM"
  />
  <SCALE
      AdNr="0"
      Calib="0 0 0 0 0 0"
      Setting="0 0 0 0 0 0 0"
  />
  <SCALE
      AdNr="1"
      Calib="0 0 0 0 0 0"
      Setting="0 0 0 0 0 0 0"
  />
  <SCALE
      AdNr="2"
      Calib="0 0 0 0 0 0"
      Setting="0 0 0 0 0 0 0"
  />
  <GSM
      PIN=""
      PORT="0"
      TLF=""
  />
</NT3Config>

답변1

grepPCRE( )와 함께 사용할 수 있습니다 -P.

grep -Po 'PGMNR=\"\K[^"]+(?=\")' file.txt
  • PGMNR=\"PGMNR="해당 부분 과 일치하고 \K일치 항목을 삭제합니다.

  • [^"]+숫자가 포함됩니다

  • 너비가 0인 정방향 예측 모드에서는 (?=\")숫자 뒤에 ".

답변2

나는 파서를 사용하여 이 질문에 답했습니다. 이것이 "올바른 방법"이라고 생각합니다.

이는 "잘못된 방법"이지만 문제를 해결하려면 최소한의 POSIX 도구를 사용해야 합니다.

grep PGMNR $filename | sed -e 's/.*PGMNR=\"//' -e 's/\".*//'

답변3

제발 - 하지 마세요. XML은 의미는 동일하지만 "패턴 일치"가 다른 많은 작업을 XML에서 수행할 수 있기 때문에 정규식 및 줄 기반 구문 분석과 잘 작동하지 않습니다.

값을 제공하는 표현식을 xmlstarlet추출할 수 있습니다 .xpath

또는 내가 가장 좋아하는 것은 Perl을 사용하여 XML::TwigXML을 구문 분석하고 그런 식으로 다시 원하는 값을 얻는 것입니다.

#!/usr/bin/env perl

use strict;
use warnings;

use XML::Twig;

my $twig = XML::Twig -> new ( 'pretty_print' => 'indented_a' ) ->  parse ( \*DATA );
print "PGMNR: ", $twig -> get_xpath('//System',0) -> att('PGMNR'),"\n";

__DATA__
<?xml version="1.0" encoding="utf-8"?>
<NT3Config>
<System Dev="7" PGMNR="24" VCONF="800 800" /> 
<WA-NT name="Soja T#1" info="23 1 1 1 61 17 00" />
<WA-NT name="MatadorM" info="23 2 2 1 61 17 00" />
<SCALE AdNr="0" Setting="0 0 0 0 0 0 0" Calib="0 0 0 0 0 0" />
<SCALE AdNr="1" Setting="0 0 0 0 0 0 0" Calib="0 0 0 0 0 0" />
<SCALE AdNr="2" Setting="0 0 0 0 0 0 0" Calib="0 0 0 0 0 0" />
<GSM TLF="" PIN="" PORT="0" />
</NT3Config>

필요한 경우 "한 줄"일 수도 있고 xmlstarletXPATH를 사용할 수도 있습니다.

perl -0777 -MXML::Twig -e 'print XML::Twig -> parse ( <> )-> get_xpath('//System',0) -> att('PGMNR');'

참고 - 정규식 기반 구문 분석을 강력히 권장하는 이유는 이것이 XML을 렌더링하는 완벽하게 유효한 방법이기 때문입니다.

<?xml version="1.0" encoding="utf-8"?>
<NT3Config>
  <System
      Dev="7"
      PGMNR="24"
      VCONF="800 800"
  />
  <WA-NT
      info="23 1 1 1 61 17 00"
      name="Soja T#1"
  />
  <WA-NT
      info="23 2 2 1 61 17 00"
      name="MatadorM"
  />
  <SCALE
      AdNr="0"
      Calib="0 0 0 0 0 0"
      Setting="0 0 0 0 0 0 0"
  />
  <SCALE
      AdNr="1"
      Calib="0 0 0 0 0 0"
      Setting="0 0 0 0 0 0 0"
  />
  <SCALE
      AdNr="2"
      Calib="0 0 0 0 0 0"
      Setting="0 0 0 0 0 0 0"
  />
  <GSM
      PIN=""
      PORT="0"
      TLF=""
  />
</NT3Config>

이:

<?xml version="1.0" encoding="utf-8"?>
<NT3Config
><System
Dev="7"
PGMNR="24"
VCONF="800 800"
/><WA-NT
info="23 1 1 1 61 17 00"
name="Soja T#1"
/><WA-NT
info="23 2 2 1 61 17 00"
name="MatadorM"
/><SCALE
AdNr="0"
Calib="0 0 0 0 0 0"
Setting="0 0 0 0 0 0 0"
/><SCALE
AdNr="1"
Calib="0 0 0 0 0 0"
Setting="0 0 0 0 0 0 0"
/><SCALE
AdNr="2"
Calib="0 0 0 0 0 0"
Setting="0 0 0 0 0 0 0"
/><GSM
PIN=""
PORT="0"
TLF=""
/></NT3Config>

이:

<?xml version="1.0" encoding="utf-8"?>
<NT3Config><System Dev="7" PGMNR="24" VCONF="800 800"/><WA-NT info="23 1 1 1 61 17 00" name="Soja T#1"/><WA-NT info="23 2 2 1 61 17 00" name="MatadorM"/><SCALE AdNr="0" Calib="0 0 0 0 0 0" Setting="0 0 0 0 0 0 0"/><SCALE AdNr="1" Calib="0 0 0 0 0 0" Setting="0 0 0 0 0 0 0"/><SCALE AdNr="2" Calib="0 0 0 0 0 0" Setting="0 0 0 0 0 0 0"/><GSM PIN="" PORT="0" TLF=""/></NT3Config>

이:

<?xml version="1.0" encoding="utf-8"?>
<NT3Config>
  <System Dev="7" PGMNR="24" VCONF="800 800"/>
  <WA-NT info="23 1 1 1 61 17 00" name="Soja T#1"/>
  <WA-NT info="23 2 2 1 61 17 00" name="MatadorM"/>
  <SCALE AdNr="0" Calib="0 0 0 0 0 0" Setting="0 0 0 0 0 0 0"/>
  <SCALE AdNr="1" Calib="0 0 0 0 0 0" Setting="0 0 0 0 0 0 0"/>
  <SCALE AdNr="2" Calib="0 0 0 0 0 0" Setting="0 0 0 0 0 0 0"/>
  <GSM PIN="" PORT="0" TLF=""/>
</NT3Config>

위의 단항 태그 중 일부가 명시적으로 꺼진 것을 볼 수도 있습니다.

<System Dev="7" PGMNR="24" VCONF="800 800"/>   

그리고:

<System Dev="7" PGMNR="24" VCONF="800 800"></System>

XML에 관한 한 둘 다 같은 말을 합니다.

이는 순전히 잠금 시스템의 추가 제약 때문에 매우 지저분한 접근 방식입니다. 하지만 위의 경고에 유의하세요. 우리는 더 이상 XML을 구문 분석하지 않고 일반 텍스트를 처리하므로 쉽게 손상될 수 있습니다. (취약한 코드는 시스템 관리자의 기분을 상하게 할 것입니다.)

#!/usr/bin/env perl

use strict;
use warnings;

local $/;
my ( $PGMNR ) = <DATA> =~ m/PGMNR=\"(\d+)\"/; 
print $PGMNR;

__DATA__
<?xml version="1.0" encoding="utf-8"?>
<NT3Config>
<System Dev="7" PGMNR="24" VCONF="800 800" /> 
<WA-NT name="Soja T#1" info="23 1 1 1 61 17 00" />
<WA-NT name="MatadorM" info="23 2 2 1 61 17 00" />
<SCALE AdNr="0" Setting="0 0 0 0 0 0 0" Calib="0 0 0 0 0 0" />
<SCALE AdNr="1" Setting="0 0 0 0 0 0 0" Calib="0 0 0 0 0 0" />
<SCALE AdNr="2" Setting="0 0 0 0 0 0 0" Calib="0 0 0 0 0 0" />
<GSM TLF="" PIN="" PORT="0" />
</NT3Config>

또는 Perl로 oneliner를 작성하십시오:

perl -0777 -e 'print <> =~ m/PGMNR=\"(\d+)\"/;'

관련 정보