2017-02-09 14 views
-1

Использование UNIX,unix команда для поиска текста и копирования полного XML

Мой файл журнала содержит несколько XML. Как я могу выполнять поиск с помощью команды или скрипта UNIX, поэтому я могу получить все XML, которые содержат abc?

Например, внизу файл журнала содержит 4 XML-файла. Я хочу, чтобы создать один новый файл который держит все XML, которые содержат **<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> 

Желание из положить в новый файл

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

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

Я пытаюсь с Grep, но только получаю 2 строк не полный XML. Начальный тег XML: <createR> и END тег </createR>.

Возможно, произойдут изменения, что все эти XML могут войти в одну строку.

ответ

1

@fresher: Попытка:

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 

В случае в полной линии, которую вы можете попробовать следующее тогда.

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 

Вскоре добавьте объяснение.

EDIT: как упомянуто ниже объяснение на таком же.

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

спасибо, но что, если есть не разрыв строки. существует вероятность, что весь XML может войти в одну строку. – fresher

+0

Будет ли пространство, если в Input_file нет новой строки? – RavinderSingh13

+0

да, будет свободное место – fresher

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

Использование \n в качестве разделителя полей и «» как разделитель записей, он будет рассматривать каждый кусок в виде одной строки, то /abc/ будет проверять каждую строку соответствует шаблону ABC или нет, если он совпадает, распечатать из
выход:

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

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

какой если, нет line break. существует вероятность, что весь XML может войти в одну строку. – fresher

+0

свежее: не могли бы вы сообщить мне, если вы попробовали мою команду. Также Хайфэн дал решение (хороший) в соответствии с вашим примером, если у вас есть какие-либо условия, которые могли бы добавить в ваш пост. – RavinderSingh13

+0

@fresher, который легко доступен, если нет места, но вы хотите его: 'sed 's @ @ \ n @' sample.csv'. просто нужно заменить конец тега createR символом новой строки за ним – haifzhan

0

Если это не все, что вам нужно:

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

затем отредактируйте свой вопрос, чтобы показать более по-настоящему репрезентативный образец ввода/вывода, который мы могли бы фактически проверить потенциальное решение, чтобы узнать, работает оно или нет.

0

Используйте инструмент XML-Aware для работы, как это:

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