Bearbeiten Sie die XML-Datei mit dem Shell-Skript / Befehl

12

Ich muss dies mit einem Unix-Skript oder einem Befehl tun. In / home / user / app / xmlfiles befindet sich eine XML-Datei wie

<book>
   <fiction type='a'>
      <author type=''></author>
   </fiction>
   <fiction type='b'>
      <author type=''></author>
   </fiction>
   <Romance>
       <author type=''></author>
   </Romance>
</book>

Ich möchte den Autorentyp in der Fiktion als lokal bearbeiten.

   <fiction>
      <author type='Local'></author>
   </fiction>

Ich muss den Autorentyp, der sich im Fiction-Tag befindet, nur mit dem Attribut b ändern . Bitte helfen Sie mir dabei mit einem Unix-Shell-Skript oder -Befehl. Vielen Dank !

VRVigneshwara
quelle
Warum nicht einen Texteditor wie vi / vim / emacs / gedit verwenden (wählen Sie einen Ihrer Wahl)? Oder können Sie nur Shell-Skripte verwenden und keine Programme verwenden?
Darius
Leider kann ich nur
Scritping
Ich würde empfehlen, xlst zu verwenden, um die Eingabe in eine entsprechende Ausgabe umzuwandeln, da dies der XMLish-Ansatz ist. Sie können XLST-Transformationen in Bash mit durchführen xlstproc. linux.byexamples.com/archives/463/xslt-processor-command-line
Frank Thomas
@FrankThomas Schauen Sie sich meine XMLish-Antwort an und sagen Sie bitte, was Sie darüber denken.
Marco M. von Hagen
@Darius Sie benötigen noch den Editor, um XML zu verstehen.
Thorbjørn Ravn Andersen

Antworten:

20

Wenn Sie nur ersetzen möchten <author type=''><\/author>mit <author type='Local'><\/author>, können Sie diese verwenden sedBefehl ein :

sed "/<fiction type='a'>/,/<\/fiction>/ s/<author type=''><\/author>/<author type='Local'><\/author>/g;" file

Beim Umgang mit XML empfehle ich jedoch einen XML-Parser / Editor wie xmlstarlet :

$ xmlstarlet ed -u /book/*/author[@type]/@type -v "Local"  file
<?xml version="1.0"?>
<book>
  <fiction>
    <author type="Local"/>
  </fiction>
  <Romance>
    <author type="Local"/>
  </Romance>
</book>

Verwenden Sie das -LFlag, um die Datei inline zu bearbeiten, anstatt die Änderungen zu drucken.

Chaos
quelle
Kommentare sind nicht für eine ausführliche Diskussion gedacht. Dieses Gespräch wurde in den Chat verschoben .
Mokubai
6

Wir könnten ein xsl-Dokument verwenden doThis.xslund das source.xmlmit xsltproczu einem verarbeiten newFile.xml.

Das xsl basiert auf der Antwort auf diese Frage .

Fügen Sie dies in eine doThis.xslDatei ein

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" omit-xml-declaration="no"/> 

<!-- Copy the entire document    -->

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<!-- Copy a specific element     -->

<xsl:template match="/book/fiction[@type='b']/author">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>

<!--    Do something with selected element  -->
            <xsl:attribute name="type">Local</xsl:attribute>

        </xsl:copy>
</xsl:template>

</xsl:stylesheet> 

Jetzt produzieren wir die newFile.xml

$:   xsltproc -o ./newFile.xml ./doThis.xsl ./source.xml 

Dies wird die sein newFile.xml

<?xml version="1.0" encoding="UTF-8"?>
<book>
   <fiction type="a">
      <author type=""/>
   </fiction>
   <fiction type="b">
      <author type="Local"/>
   </fiction>
   <Romance>
       <author type=""/>
   </Romance>
</book>

Der Ausdruck, der verwendet wird, um Fiktion vom Typ b zu finden, ist XPath.

Marco M. von Hagen
quelle
6
xmlstarlet edit --update "/book/fiction[@type='b']/author/@type" --value "Local" book.xml
Kit
quelle
4
Eine etwas ausführlichere Erklärung und ein Link zur Dokumentation würden Ihre Antwort hilfreicher machen.
Davidbaumann
3
Das liefert nicht wirklich mehr Infos. Es wäre hilfreicher, wenn Sie Ihren Beitrag bearbeiten , vollständige Sätze verwenden und Ihre eine Codezeile erklären würden.
Slhck
man xmlstarlet
Kit
Diese Antwort ist ungefähr so ​​perfekt wie eine Antwort sein kann, IMO!
wilbur4321
2

Es ist ganz einfach mit sed. Das folgende Skript ändert den Inhalt der Datei a.xmlund legt das Original a.bakals Backup ab.

Es durchsucht jede Datei nach der Zeichenfolge <author type=''>und ersetzt sie durch <author type='Local'>. Der /gModifikator bedeutet, dass versucht wird, wenn möglich mehr als 1 Ersetzung in jeder Zeile vorzunehmen (für Ihre Beispieldatei nicht erforderlich).

sed -i.bak "s/<author type=''>/<author type='Local'>/g" a.xml
Marki555
quelle
Ich muss den Autorentyp ändern, der nur im Fiction-Tag enthalten ist. Ist das möglich, dies zu überprüfen? Ich denke, der obige Code wird alle Autoren-Tags ändern.
VRVigneshwara
Dann hättest du das in deiner Frage angeben sollen :) Ich sehe, du hast das Q bereits bearbeitet ... und auch eine bessere Antwort bekommen.
Marki555