2017-02-09 4 views
-1

UNIX verwenden,Unix-Befehl Text zu suchen und zu kopieren vollständige XML

Meine Protokolldatei mehr XML-Code enthält. Wie kann ich mit UNIX-Befehl oder -Skript suchen, damit ich alle XML-Dateien, die contain abc enthalten, bekommen kann?

Zum Beispiel enthält die Protokolldatei 4 XMLs. Ich möchte eine neue Datei erstellen, die alle XML halten, die **<value>abc</value>**

<createR>   <----- this is starting tag of XML 
<value>abc</value> <----- search for this value 
<val>xyz</val> 
</createR>   <----- this is end tag of XML 

<createR> 
<value>123</value> 
<val>xyz</val> 
</createR> 

<createR> 
<value>abc</value> 
<val>xyz</val> 
</createR> 

<createR> 
<value>qpw</value> 
<val>xyz</val> 
</createR> 

Wunsch heraus setzen in neue Datei enthalten

<createR> 
<value>abc</value> 
<val>xyz</val> 
</createR> 

<createR> 
<value>abc</value> 
<val>xyz</val> 
</createR> 

ich mit grep bin versucht, aber nur 2 Zeile nicht vollständig XML bekommen. Das XML-Start-Tag ist <createR> und das END-Tag </createR>.

Es könnte sich ändern, dass alle diese XML in einer einzigen Zeile protokolliert werden können.

Antwort

1

@fresher: Versuchen:

awk '/<\/createR>/{A="";if(P){print Q ORS $0};Q=P=""} /<createR>/{A=1} A{Q=Q?Q ORS $0:$0;if($0 ~ /<value>abc<\/value>/){P=1}}' Input_file 

Falls es in komplette Zeile, die Sie dann folgende versuchen könnte.

awk '/<\/createR>/{A="";if(P){print Q ORS $0};Q=P=""} /<createR>/{A=1} A{Q=Q?Q ORS $0:$0;if($0 ~ /<value>abc<\/value>/){P=1}}' RS=" " Input_file 

Wird kurz Erklärung hinzufügen.

EDIT: wie im Folgenden erwähnt ist die Erklärung zu gleichen.

awk 
'/<\/createR>/    ##### Searching for string "</createR>" here. 
           ##### If above condition is TRUE then execute all following statements. 
{A="";      ##### Nullify the variable A's value, will explain A's existence in next steps. 
if(P){      ##### If variable P's value exist then do following. 
print Q ORS $0};    ##### print the value of variable Q then ORS(Output record separator) then $0(current line)'s values. 
Q=P=""}      ##### Nullifying the values of variables Q and P now. 
/<createR>/     ##### Searching for string "<createR>" here. 
{A=1}       ##### Set the value of variable A to 1. 
A{       ##### If variable A's value is 1 then do following. 
Q=Q?Q ORS $0:$0;    ##### creating a variable named Q whose value will be appended with values of current lines with ORS. 
if($0 ~ /<value>abc<\/value>/)##### checking if current line's value has abc in it as per OP's request. If yes then 
{P=1}       ##### Set the variable named P's value to 1. 
}' 
+0

Danke, aber was, wenn es nicht Zeilenumbruch. Es besteht die Möglichkeit, dass alle XML-Dateien in einer einzigen Zeile geloggt werden. – fresher

+0

Wird es Platz geben, wenn in Input_file keine neue Zeile vorhanden ist? – RavinderSingh13

+0

ja, es wird sicher Platz geben – fresher

2
awk 'BEGIN{RS=""; FS="\n"}/abc/{print $0 "\n"}' sample.csv  

Verwenden \n als Feldtrennzeichen und „“ als Datensatztrennzeichen, wird es jeden Chunk als eine Zeile behandeln, dann /abc/ jede Zeile überprüfen wird entspricht das abc-Muster oder nicht, ob sie paßt, ausdrucken out
Ausgang:

<createR> 
<value>abc</value> 
<val>xyz</val> 
</createR> 

<createR> 
<value>abc</value> 
<val>xyz</val> 
</createR> 
+0

was ist, wenn es keinen Zeilenumbruch gibt. Es besteht die Möglichkeit, dass alle XML-Dateien in einer einzigen Zeile geloggt werden. – fresher

+0

frischer: Könnten Sie bitte lassen Sie mich wissen, wenn Sie mein Kommando versucht haben. Auch Haifeng hat eine Lösung (nette) nach Ihrer Probe gezeigt, wenn Sie irgendwelche Bedingungen in Ihrem Beitrag hinzufügen können. – RavinderSingh13

+0

@fresher das ist quit einfach zu erreichen, wenn es keinen Platz gibt, aber Sie wollen es: 'sed 's @ @ \ n @' sample.csv'. muss nur das Ende createR Tag mit Newline-Zeichen dahinter ersetzen – haifzhan

0

ist dies nicht alles, was Sie brauchen:

$ awk -v RS= -v ORS='\n\n' '/abc/' file 
<createR>   <----- this is starting tag of XML 
<value>abc</value> <----- search for this value 
<val>xyz</val> 
</createR>   <----- this is end tag of XML 

<createR> 
<value>abc</value> 
<val>xyz</val> 
</createR> 

dann bearbeiten Sie Ihre Frage, um mehr wirklich repräsentative Beispiel Eingabe/Ausgabe zu zeigen, dass wir tatsächlich eine mögliche Lösung gegen testen könnten, ob es funktioniert oder nicht.

0

Verwenden Sie ein XML-fähiges Tool für Jobs wie folgt aus:

xmlstarlet sel -t -c "//value[text()='abc']/.." input.xml 
Verwandte Themen