XML 파일의 특정 줄을 함께 연결하면 됩니다.

XML 파일의 특정 줄을 함께 연결하면 됩니다.

이 XML을 다음으로 변환하고 싶습니다.확증하다서로 연결된 선. 이렇게 하면 나중에 특정 줄만 잡을 수 있습니다. 이 XML이 속성을 사용한 경우 데이터는 이미 1개의 행에 있습니다. 이 작업을 수행하기 위해 XSLT를 사용하고 싶지 않습니다. grep, sed, awk, xmlstarlet, xpath가 좋을 것입니다.

따라서 한 행에 가 포함되어 있으면 "<instruction>"다음 4개 행을 가져와 모두 한 행에 배치해야 합니다. 쉼표가 없습니다. 다음과 같습니다.

게시된 질문과 다릅니다.여기: "참여" 순서를 시작할 날짜로 모드를 설정합니다.

awk '
    /\<instruction\>/ && line {print line; line=""}
    {line = line ? line" "$0 : $0}
    END {print line}
'

이렇게 하면 줄이 닫히는 태그로 축소되지만 닫는 태그 줄 자체가 소개되지는 않습니다.

플랫폼은 Windows 2012R2 서버에 있습니다. Gnu 유틸리티가 설치됩니다. 파일 크기는 약 100k입니다.

                        <instruction>
                          <name>AAAAA</name>
                          <value>WHITE</value>
                          <type>0</type>
                        </instruction>
                        <instruction>
                          <name>BBBBB</name>
                          <value>WHITE</value>
                          <type>0</type>
                        </instruction>
                        <instruction>
                          <name>CCCCC</name>
                          <value>WHITE</value>
                          <type>0</type>
                        </instruction>
                      <routing/>
                      <phantom>False</phantom>
                      <AssemblyHistory/>

원하는 출력: (줄 바꿈할 수 있지만 지시문 요소는 모두 한 줄에 있어야 합니다)

<instruction><name>AAAAA</name><value>WHITE</value><type>0</type></instruction> <instruction><name>BBBBB</name><value>WHITE</value><type>0</type></instruction> <instruction><name>CCCCC</name><value>WHITE</value><type>0</type></instruction> <routing/> <phantom>False</phantom> <AssemblyHistory/>

비슷한 예(잘못된 XML)

data line 2
cust:
tommy
smith
123 main
endcust
data line 16
TRACE: error at xy123
cust:
mary 
smith
444 broadway
endcust
LOG: logon tty3
LOG: free memory before gc 33453211
root: ps -ealf  tty0 


data line 2
cust: tommy smith123 main endcust
data line 16
TRACE: error at xy123
cust:mary smith444 broadway endcust
LOG: logon tty3
LOG: free memory before gc 33453211
root: ps -ealf  tty0 

줄을 생략하지 않고 전체 파일을 표준 출력으로 복사합니다. "cust:"를 찾으면 다음 중 하나를 수행할 수 있습니다. 1) 다음 4줄을 결합하거나 2) "endcust"를 찾을 때까지 줄을 결합합니다.

마찬가지지만 이번에는 XML 도구를 사용할 수 없습니다. 그렇다면 이런 상황이 발생하면 어떻게 해결하시겠습니까? 가장 중요한 질문이 XML이라면 좋습니다. 그렇지 않은 경우 두 번째 예를 사용하십시오.

답변1

sed의 범위 연산자를 사용하여 문제를 해결할 수 있지만 그렇게 하기 전에 동일한 줄에서 토큰을 처리하고 플래그를 해제해야 합니다. 동일한 줄에 있는 여러 태그도 처리되지 않습니다.

sed -e '
    s/^[[:blank:]]*//
    \|<instruction>.*</instruction>|b
    \|<instruction>|,\|</instruction>|!b
    H;\|</instruction>|!d
    s/.*//;x;s/\n[[:blank:]]*//g;s/^\n//
' input_xml_lookalike_file

답변2

grep/sed/awk를 사용하려는 이유는 익숙하기 때문인 것 같습니다. 하지만 그렇다고 해서 작업에 적합한 도구가 되는 것은 아닙니다. 단지 사용법을 안다고 해서 드라이버를 사용하여 못을 박는 것은 현명한 생각이 아닙니다.

이를 달성하려면 XSLT 또는 XQuery와 같은 XML 인식 도구가 필요합니다. (우선, 태그에는 <instruction>공백이 전혀 포함되지 않을 것이라고 생각하는 이유는 무엇입니까? 그리고 지시어 요소의 내용은 항상 4줄에 걸쳐 펼쳐져 있다고 생각합니까?)

StackOverflow의 많은 사용자는 특정 방식으로 형식화된 XML을 생성하는 방법을 묻고 이로 인해 XML 도구 선택이 제한됩니다. 왜 이렇게 해야 하는지 묻는다면 항상 누군가가 awk, grep 또는 Perl과 같은 XML을 인식하지 않는 도구를 사용하여 XML을 읽는 애플리케이션을 작성했다고 대답합니다. 이렇게 하면 XML의 전체 요점(및 XML이 제공하는 모든 상호 운용성 이점)을 잃게 됩니다.

답변3

valueinstruction예를 들어 값이 사용되는 하위 name노드 도 있는 각 노드의 하위 노드 값을 추출합니다.Exterior ColorXML 스타:

xmlstarlet sel -v '//instruction[name = "Exterior Color"]/value' -nl file.xml

주어진 파일

<?xml version="1.0"?>
<AssemblyHistory>
  <routing>
    <instruction>
      <name>Interior Finish</name>
      <value>WHITE</value>
      <type>0</type>
    </instruction>
    <instruction>
      <name>Exterior Color</name>
      <value>WHITE</value>
      <type>0</type>
    </instruction>
    <instruction>
      <name>Base Vinyl Color</name>
      <value>WHITE</value>
      <type>0</type>
    </instruction>
  </routing>
  <phantom>False</phantom>
</AssemblyHistory>

그러면 문자열이 반환됩니다 WHITE.

다음은 모든 노드에 name해당하는 각 값을 반환합니다.WHITEinstruction

xmlstarlet sel -t -v '//instruction[value = "WHITE"]/name' -nl  file.xml

답변4

이것은 거의 작동합니다.

awk 'BEGIN {RS="<instruction>"; FS="\n"; OFS=""} NR>1 {$1=RS; NF--; print}'

그러나 이전 줄을 건너뛰고 /instruction 태그를 볼 때 결합을 중단하지 않습니다.

input:
LINE 0
LINE 1
LINE 2
<instruction>
<name>Glass SQFT</name>
<value>7.02</value>
<type>0</type>
</instruction>
LINE 3

output:
<instruction><name>Glass SQFT</name><value>7.02</value><type>0</type></instruction>LINE 3

관련 정보