여러 파일이 있는 heredoc 내부의 변수

여러 파일이 있는 heredoc 내부의 변수

XML 콘텐츠가 포함된 Heredoc이 있고 다음과 같은 다른 파일의 콘텐츠를 추가했습니다.

bar문서:

<bar>
  $baz
</bar>

스크립트:

bar=$(cat bar.xml)

# this would be the ideal, of course it doesn't work
baz=$(cat baz.xml)
#

cat << EOF > out.xml
<foo>
  $bar
</foo>
EOF

출력 out.xml:

<foo>
  <bar>
    $baz
  </bar>
</foo>

이제 다음에 세 번째 파일을 추가하고 싶습니다 bar.

baz문서:

<baz>baz<baz>

그래서 최종 내용 out.xml은 다음과 같습니다.

<foo>
  <bar>
    <baz>baz</baz>
  </bar>
</foo>

이 작업 흐름에서는 (대형) xml 파일을 각각 자체 구성 요소가 있는 구성 요소로 분리할 수 있다고 가정합니다.

master (heredoc) xml
  ^^^
  second xml
    ^^^
    third xml

가능한 한 간단하게 만들고 싶기 때문에 어디서부터 시작해야할지 모르겠습니다. 도움을 주시면 감사하겠습니다.

답변1

XML 문서를 결합하는 관용적 방법은 다음을 사용하는 것입니다.XSLT.먼저 몇 가지 설정은 다음과 같습니다.

$ cd "$(mktemp --directory)"
$ echo '<foo/>' > ./foo.xml
$ echo '<bar/>' > ./bar.xml
$ echo '<baz/>' > ./baz.xml

그런 다음 파일 내용을 소스 파일의 요소에 삽입하고 파일의 나머지 부분을 있는 그대로 복사하는 XSLT 파일을 만듭니다.

$ cat > ./insert.xslt <<'EOF'
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
>     <xsl:template match="@* | node()">
>         <xsl:copy>
>             <xsl:apply-templates select="@* | node()"/>
>             <xsl:if test="name() = $element">
>                 <xsl:copy-of select="document($file)"/>
>             </xsl:if>
>         </xsl:copy>
>     </xsl:template>
> </xsl:stylesheet>
> EOF

이제 어떤 파일이든 다른 파일에 삽입할 수 있습니다.

$ xsltproc --output ./bar-insert.xml --stringparam file ./baz.xml --stringparam element bar ./insert.xslt ./bar.xml
$ cat ./bar-insert.xml
<?xml version="1.0"?>
<bar><baz/></bar>

반복하여 최종 파일을 생성해 보겠습니다.

$ xsltproc --output ./foo-insert.xml --stringparam file ./bar-insert.xml --stringparam element foo ./insert.xslt ./foo.xml
$ cat ./foo-insert.xml
<?xml version="1.0"?>
<foo><bar><baz/></bar></foo>

이것의 장점은 들여쓰기 여부, 빈 요소 축소 여부 등 모든 XML 파일을 처리할 수 있다는 것입니다.


여러 번 참조되는 경우 파일을 여러 번 삽입할 수도 있습니다. 예를 들어 people.xml이 주어진 경우:

<people>
    <managers>
        <name>Jane Doe</name>
        <reports>
            <insert/>
        </reports>
    </managers>
    <interns>
        <insert/>
    </interns>
</people>

및 insert.xml:

<name>Abe Lincoln</name>

이제 다음 두 위치에 insert.xml을 쉽게 배치할 수 있습니다.

$ xsltproc --stringparam file ./insert.xml --stringparam element insert ./insert.xslt ./people.xml 
<?xml version="1.0"?>
<people>
    <managers>
        <name>Jane Doe</name>
        <reports>
            <insert><name>Abe Lincoln</name></insert>
        </reports>
    </managers>
    <interns>
        <insert><name>Abe Lincoln</name></insert>
    </interns>
</people>

답변2

여기서 사용할 수 있습니다 envsubst:

bar=$(baz=$(cat baz.xml) envsubst '$baz' < bar.xml) envsubst '$bar' << 'EOF'
<foo>
  $bar
</foo>
EOF

$bar이렇게 하면 // ${bar}/만 확장되고 다른 확장(, , , ...)이나 다른 변수는 확장 되지 않습니다 $baz. 예:${baz}$(cmd)`cmd`$((arith))${x#y}

bar=$(cat bar.xml)
baz=$(cat baz.xml)
eval "cat << EOF
<foo>
  $bar
</foo>
EOF"

방법.

답변3

이 솔루션을 찾았지만 더 나은 솔루션이 있는지 모르겠습니다.

sed -i '/<bar>/r baz.xml' bar.xml

그런 다음 구분 기호가 옵니다.

bar=$(cat bar.xml)

cat << EOF > out.xml
<foo>
  $bar
</foo>
EOF

원하는 결과를 출력합니다.

<foo>
  <bar>
    <baz>baz</baz>
  </bar>
</foo>

관련 정보