2010-08-27 4 views
3

У меня есть файл событий, который имеет несколько событий с несколькими выровненными между <event> и </event> тегами. Я хочу распечатать все событие От <event> до </event>, только если строка внутри этого события содержит либо строку uniqueId = "1279939300.862594_PFM_1_1912320699", либо uniqueId = "1281686522.353435_PFM_1_988171542". Файл содержит 100000 событий, и каждое событие имеет от 20 до 35 строк (атрибуты в событии различаются по длине). Я начал использовать sed, но вам нужна небольшая помощь:Как напечатать раздел файла между двумя регулярными выражениями, только если строка внутри раздела содержит определенную строку внутри него

cat xmlEventLog_2010-03-23T* | sed -nr "/<event eventTimestamp/,/<\/event>/" 

Что нужно сделать, чтобы закончить это? Кроме того, sed является лучшим способом сделать это с учетом размера файлов?

Заранее спасибо

Я хотел изменить это, чтобы обновить. По некоторым причинам я хочу сделать это с помощью sed. Я попробовал решение Дениса, но он не работает:

bash$ grep 1279939300.862594_PFM_1_1912320699 xmlEventLog* 
xmlEventLog_2010-03-23T02:41:15_PFM_1_1.xml: <event eventTimestamp="2010-03-23T02:41:40.861" originalReceivedMessageSize="0" uniqueId="1279939300.862594_PFM_1_1912320699"> 
bash$ grep 1281686522.353435_PFM_1_988171542 xmlEventLog* 
xmlEventLog_2010-03-23T07:47:38_PFM_1_1.xml: <event eventTimestamp="2010-03-23T08:02:02.299" originalReceivedMessageSize="685" uniqueId="1281686522.353435_PFM_1_988171542"> 
bash$ time sed -n ':a; /<event>/,/<\/event>/ N; /<event>/,/<\/event>/!b; /<\/event>/ {/uniqueId="1279939300.862594_PFM_1_1912320699"\|uniqueId="1281686522.353435_PFM_1_988171542"/p;d}; ba' xmlEventLog* 

real 1m13.134s 
user 1m12.463s 
sys  0m0.659s 
bash$ 

Который явно ничего не возвращал. Так можно ли это сделать с sed?

ответ

1

Дайте этому попытку:

sed -n ':a; /<event>/,/<\/event>/ N; /<event>/,/<\/event>/!b; /<\/event>/ {/uniqueId="1279939300.862594_PFM_1_1912320699"\|uniqueId="1281686522.353435_PFM_1_988171542"/p;d}; ba' 
+0

после того, как 15 минут ожидания этого еще не вернули ответ. Вероятно, он больше подходит для небольших файлов. Спасибо, хотя для multi line sed. Это на уровне, который я еще не использовал, поэтому изучу его и узнаю от него. – amadain

+0

@amadain: У меня было несколько ошибок. См. Отредактированную версию. –

+0

dennis a означает добавление строки и используется после соответствия шаблону (из того, что я мог найти). Не могли бы вы объяснить, что он здесь делает в качестве единственной команды: a? – amadain

2
awk -vRS="</event>" '/<event>/ && /1279939300.862594_PFM_1_1912320699|1281686522.353435_PFM_1_988171542/{print}' file 
+0

Это работал гениальные спасибо. Теперь я проверяю время против sed, показанного выше, чтобы увидеть, какой из них лучше, чем время (поскольку мои файлы огромны). Вот что: real 3m4.890s пользователь 3m2.273s sys 0m2.568s – amadain

0

Вы должны иметь возможность вставлять уникальные идентификаторы непосредственно в регулярное выражение, используя | характер, чтобы либо UniqueID. Я сделал быстрый тест и следующее регулярное выражение, кажется, найти правильные записи:

<event.*?uniqueid=("1279939300\.862594_PFM_1_1912320699"|"1281686522\.353435_PFM_1_988171542").*?</event> 
+0

uniqueId не обязательно находится на той же строке, что и тег amadain

+0

Должен признать, что я не знаком с sed, но нет ли переключателя для включения многострочных регулярных выражений? –

+0

да. Я пытаюсь использовать многострочный сериал Денниса сверху. Один awk работал около 3 минут – amadain