Mit Bash,
Datei:
<?xml version="1.0" encoding="UTF-8"?>
<blah>
<blah1 path="er" name="andy" remote="origin" branch="master" tag="true" />
<blah1 path="er/er1" name="Roger" remote="origin" branch="childbranch" tag="true" />
<blah1 path="er/er2" name="Steven" remote="origin" branch="master" tag="true" />
</blah>
Ich habe folgendes versucht:
grep -i 'name="andy" remote="origin" branch=".*\"' <filename>
Aber es gibt die ganze Zeile zurück:
<blah1 path="er" name="andy" remote="origin" branch="master" tag="true" />
Ich möchte die Linie anhand der folgenden Punkte anpassen:
name="andy"
Ich möchte nur, dass es zurückkommt:
master
Antworten:
Verwenden Sie einen XML-Parser zum Parsen von XML-Daten. Mitxmlstarlet Es wird nur eine XPath-Übung:
quelle
name="andy" branch="foo"
oder ändert die Zeichenkodierung oder fügt ein Escape\"
in dasbranch
Attribut ein, oder oder oder ... Ich stimme zu; Verwenden Sie einfach einen XML-Parser!branch=$(xmllint --xpath 'string(//blah1[@name="andy"]/@branch)' file.xml)
ist der entsprechende Befehl mit xmllint.Verwenden Sie xmllint, um den Wert des Attributs mit XPath zu extrahieren:
Es ist besser, einen XML-Parser zum Verarbeiten von XML zu verwenden, da sich die Reihenfolge der Attribute ändern kann und Zeilenumbrüche eingefügt werden können, sodass sich die Namens- und Verzweigungsattribute in verschiedenen Zeilen der Datei befinden.
quelle
Mit
grep
:-P
Aktivieren Sie reguläre Perl-Ausdrücke (PCRE).-i
Fall ignorieren-o
Drucken Sie nur übereinstimmende TeileIn der Regex
\K
ist dies ein Look mit einer Breite von Null, der mit dem Teil vor dem übereinstimmt\K
, ihn jedoch nicht in die Übereinstimmung einbezieht .quelle
blah1
) Element mit ähnlichen Attributen gibt? Was ist, wenn der Filialname enthält\"
? Auch warum-i
? Bei XML-Element- und Attributnamen wird zwischen Groß- und Kleinschreibung unterschieden. All diese Dinge sind Fehler, die darauf warten, irgendwann in der Zukunft aufzutauchen. Ich empfehle, das richtige Werkzeug für den Job zu verwenden. ein XML-Parser.-i
stammt aus OP und kann nützlich sein, um mit den Attributwerten umzugehen (Roger, Steven). Wenn der Filialname einen hatte\"
, sollte er mit maskiert worden sein\"
. Ja, Sie haben Recht, XML kann sich ändern, Zeilenumbrüche usw. aufweisen. Ein XML-Parser ist definitiv die bessere Antwort, aber OP hat darum gebeten,grep
und es könnte sein, dass er weiß, was er tut.Verwenden von
awk
:Dadurch wird eine Zeile gefunden, die
name="andy"
jedes Feld in dieser Zeile enthält, und anschließend durchlaufen. Wenn das Feld enthält, werdenbranch=
wirbranch=
alle doppelten Anführungszeichen entfernen und den Rest des Feldes drucken.sub(/branch=/, "")
sucht nach einem Match vonbranch=
und ersetzt es durch""
(nichts)gsub ist ähnlich, außer dass es global ersetzt wird (alle Vorkommen anstelle nur des ersten Vorkommens).
quelle
Ich denke das funktioniert:
Das
awk
Teil stellt sicher, dass nurbranch="master"
zurückgegeben wird. Dassed
Teil gibt mit einer Referenz zurück, was zwischen den doppelten Anführungszeichen steht (das\1
stimmt mit dem Teil zwischen den Klammern überein).Jetzt weiß ich, dass es hier draußen eine Menge Leute gibt, die viel mehr über die Kunst wissen, die awk und sed ist, also bin ich auf Kritik vorbereitet :-)
quelle
Wenn Sie auf Ihrem Computer keinen Zugriff auf xmllint oder xmlstarlet haben. Stellen Sie sicher, dass Sie Ihre XML in eine Zeile umwandeln, bevor Sie grep wie dieses verwenden
Jetzt sind Sie sicher, dass Tags nicht in separaten Zeilen aufgeteilt werden
wird ausgeschnitten (wie in xpath / blah1 [@ name = "andy"])
jetzt
wird zurückkehren (wie in xpath / @ branch)
Meister
alle zusammen
quelle