2013-05-21 9 views
24

Ich habe eine Datei enthält die folgenden Zeilen:Wie sed verwenden String zu extrahieren

<parameter name="PortMappingEnabled" access="readWrite" type="xsd:boolean"></parameter> 
    <parameter name="PortMappingLeaseDuration" access="readWrite" activeNotify="canDeny" type="xsd:unsignedInt"></parameter> 
    <parameter name="RemoteHost" access="readWrite"></parameter> 
    <parameter name="ExternalPort" access="readWrite" type="xsd:unsignedInt"></parameter> 
    <parameter name="ExternalPortEndRange" access="readWrite" type="xsd:unsignedInt"></parameter> 
    <parameter name="InternalPort" access="readWrite" type="xsd:unsignedInt"></parameter> 
    <parameter name="PortMappingProtocol" access="readWrite"></parameter> 
    <parameter name="InternalClient" access="readWrite"></parameter> 
    <parameter name="PortMappingDescription" access="readWrite"></parameter> 

Ich möchte auf diese Datei nur die Parameternamen zu extrahieren Befehl auszuführen, wie in der folgenden Ausgabe angezeigt:

$sedcommand file.txt 
PortMappingEnabled 
PortMappingLeaseDuration 
RemoteHost 
ExternalPort 
ExternalPortEndRange 
InternalPort 
PortMappingProtocol 
InternalClient 
PortMappingDescription 

Was könnte dieser Befehl sein?

+1

Beachten Sie, dass Sie traurig sein werden, wenn dieses XML in mehreren Zeilen zu Ihnen kommt oder wenn sich die Reihenfolge der Argumente ändert. Wenn das überhaupt möglich ist, sollten Sie einen geeigneten XML-Parser verwenden. –

+0

Hm, Doppelstandard mit Fragen, die in 10 Sekunden beantwortet werden können, gegenüber denen, die mehr Zeit benötigen? Wo wird der Post gefragt, was Sie versucht haben? Oh warte ... – rliu

Antwort

24

Sie möchten awk.

Dies wäre ein quick and dirty Hack:

awk -F "\"" '{print $2}' /tmp/file.txt

PortMappingEnabled 
PortMappingLeaseDuration 
RemoteHost 
ExternalPort 
ExternalPortEndRange 
InternalPort 
PortMappingProtocol 
InternalClient 
PortMappingDescription 
+0

'cut' wird den Job schneller machen :-) –

36

sed 's/[^"]*"\([^"]*\).*/\1/'

macht die Arbeit.

+6

+1 Schön, einfach und elegant !!! Liebe es!!! – Barranka

+32

Das ist weder einfach noch elegant. Einfach kryptisch. – Stefan

+11

@Stefan, vielleicht dem ungeübten Auge. Aber verbringen Sie Zeit mit RegEx und wie Jazz oder Picasso, Sie werden die schlichte Schönheit zu schätzen wissen. – SaxDaddy

64

grep geboren wurde, Dinge zu extrahieren:

grep -Po 'name="\K[^"]*' 

Test mit Ihren Daten:

kent$ echo '<parameter name="PortMappingEnabled" access="readWrite" type="xsd:boolean"></parameter> 
    <parameter name="PortMappingLeaseDuration" access="readWrite" activeNotify="canDeny" type="xsd:unsignedInt"></parameter> 
    <parameter name="RemoteHost" access="readWrite"></parameter> 
    <parameter name="ExternalPort" access="readWrite" type="xsd:unsignedInt"></parameter> 
    <parameter name="ExternalPortEndRange" access="readWrite" type="xsd:unsignedInt"></parameter> 
    <parameter name="InternalPort" access="readWrite" type="xsd:unsignedInt"></parameter> 
    <parameter name="PortMappingProtocol" access="readWrite"></parameter> 
    <parameter name="InternalClient" access="readWrite"></parameter> 
    <parameter name="PortMappingDescription" access="readWrite"></parameter> 
'|grep -Po 'name="\K[^"]*' 
PortMappingEnabled 
PortMappingLeaseDuration 
RemoteHost 
ExternalPort 
ExternalPortEndRange 
InternalPort 
PortMappingProtocol 
InternalClient 
PortMappingDescription 
+4

Nur FYI, von der grep-Manpage bezüglich '-P':" Das ist sehr experimentell und ** grep -P ** kann vor nicht implementierten Features warnen. " –

+0

Nicht alle * nix distros unterstützen 'grep -o'. Eine Instanz, die ich kenne, ist AIX –

+0

@FukuzawaYukio Ich denke, die Grep von Ubuntu Linux ausgeliefert sollte es richtig unterstützen? obwohl ich nicht ubuntu user bin. Die Frage wurde mit Linux & Ubuntu getaggt, nicht mit Unix oder Aix. Aber Sie kommentieren richtig. – Kent

12

Sie XML nicht analysieren sollten Werkzeuge wie sed oder awk verwenden. Es ist fehleranfällig.

Wenn sich die Eingabe ändert und vor dem Namensparameter ein Zeilenwechselzeichen anstelle des Leerzeichens angezeigt wird, wird es eines Tages ausfallen und zu unerwarteten Ergebnissen führen.

Wenn Sie wirklich sicher sind, dass Ihre Eingabe immer auf diese Weise formatiert wird, können Sie verwenden. Es ist schneller als sed und awk:

cut -d'"' -f2 < input.txt 

Es wird besser sein, sie zuerst zu analysieren, und nur Attribut Parameternamen extrahieren:

xpath -q -e //@name input.txt | cut -d'"' -f2 

mehr über XPath zu lernen, dieses Tutorial sehen: http://www.w3schools.com/xpath/