2013-05-21 15 views
24

Ho un file che contiene le seguenti righe:Come utilizzare sed per estrarre sottostringa

<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> 

voglio eseguire il comando su questo file per estrarre solo i nomi dei parametri che vedi nell'immagine seguente output:

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

Quale potrebbe essere questo comando?

+1

Nota che sarai triste quando quell'XML ti arriverà su più righe o se l'ordine degli argomenti cambia. Se questa è una possibilità, ti consigliamo di utilizzare un parser XML appropriato. –

+0

Hm, doppio standard con domande a cui è possibile rispondere in 10 secondi rispetto a quelle che richiedono più tempo? Dov'è il post che chiede cosa hai provato? Oh aspetta ... – rliu

risposta

24

Si desidera awk.

Questo sarebbe un hack rapido e sporco:

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

PortMappingEnabled 
PortMappingLeaseDuration 
RemoteHost 
ExternalPort 
ExternalPortEndRange 
InternalPort 
PortMappingProtocol 
InternalClient 
PortMappingDescription 
+0

'cut' farà il lavoro più velocemente :-) –

36

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

fa il lavoro.

+6

+1 Bello, semplice ed elegante !!! Lo adoro!!! – Barranka

+32

Non è né semplice né elegante. Semplicemente criptico. – Stefan

+11

@Stefan, forse per l'occhio inesperto. Ma trascorri del tempo con RegEx e, come il jazz o Picasso, apprezzerai la bellezza semplice. – SaxDaddy

64

grep è nato per estrarre le cose:

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

test con i tuoi dati:

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

Solo FYI, dalla pagina di grep relativa a '-P':" Questo è altamente sperimentale e ** grep -P ** potrebbe mettere in guardia sulle funzionalità non implementate. " –

+0

Non tutte le distribuzioni * nix supportano 'grep -o'. Un esempio che conosco è AIX –

+0

@FukuzawaYukio Penso che il grep fornito da ubuntu linux dovrebbe supportarlo giusto? anche se non sono un utente di Ubuntu. La domanda è stata taggata con Linux e ubuntu, non con Unix o Aix. Ma il tuo commento è corretto. – Kent

12

Non si dovrebbe analizzare XML utilizzando strumenti come sed o awk. È soggetto a errori.

Se l'input cambia, e prima del parametro name si otterrà un carattere di nuova riga invece dello spazio, un giorno non sarà possibile produrre risultati imprevisti.

Se sei veramente sicuro che il tuo input sarà sempre formattato in questo modo, puoi utilizzare cut. E 'più veloce di sed e awk:

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

Sarà meglio per analizzare un primo momento, ed estrarre unico attributo nome del parametro:

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

Per saperne di più su XPath, vedere questo tutorial: http://www.w3schools.com/xpath/

Problemi correlati