Нужна помощь, чтобы вернуть все данные в файл журнала с двумя определенными разделителями. Обычно у нас есть журналы, подобные приведенному ниже:
2018-04-17 03:59:29,243 TRACE [xml] This is just a test.
2018-04-17 13:22:24,230 INFO [properties] I believe this is another test.
2018-04-18 03:48:07,043 ERROR [properties] (Thread-13) UpdateType: more data coming here; ProcessId: 5010
2018-04-17 13:22:24,230 INFO [log] I need to retrieve this string here
and also this one as it is part of the same text
2018-04-17 13:22:24,230 INFO [det] I believe this is another test.
Если я введу grep «здесь», я просто получу строку, включающую слово, но мне действительно нужно получить весь текст, разрывы, вероятно, также способствуют моей проблеме.
2018-04-17 13:22:24,230 INFO [log] I need to retrieve this string here
and also this one as it is part of the same text
У нас может быть несколько «здесь» в файле журнала. Я попытался сделать это через sed, но не могу найти правильный способ использовать разделители, которые, как мне кажется, должны быть всей DATE.
Я очень ценю вашу помощь в этом.
Новый пример после комментариев Каракфы
2018-04-17 03:48:07,044 INFO [passpoint-logger] (Thread-19) ERFG|1.0||ID:414d512049584450414153541541871985165165130312020203aa4b|Thread-19|||2018-04-17 03:48:07|out-1||out-1|
2018-04-17 03:59:29,243 TRACE [xml] (Thread-19) RAW MED XML: <?xml version = "1.0" encoding = "UTF-8" standalone = "yes"?><MED:MED_PMT_Tmp_Notif xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns = "http://services.xxx.com/POQ/v01" xmlns:POQ = "http://services.xxx.com/POQ/v01" xmlns:MED = "http://services.xxx.com/MED/v1.2" version = "1.2.3" messageID = "15290140135778972043" Updat584ype = "PGML" xsi:schemaLocation = "http://services.xxx.com/MED/v1.2 MED_PMT_v.1.2.3.xsd">
<MED_Space xmlns:ns2 = "http://services.xxx.com/MED/v1.2" xmlns:ns4 = "http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns3 = "http://services.xxx.com/POQ_Header/v01" status = "AVAIL" dest = "MQX" aircraftType = "DH8" aircraftConfig = "120">
<Space_ID partition = "584" orig = "ADD3" messageCreate = "2018-04-17T03:59:29.202-05:00">
<Space carrier = "584" date = "2018-04-18">0108</Space>
</Space_ID>
<DepartAndArrive estDep = "2018-04-18T18:10:00+03:00" schedDep = "2018-04-18T18:10:00+03:00" estArrival = "2018-04-18T19:30:00+03:00" schedArrival = "2018-04-18T19:30:00+03:00"/>
<Sched_OandD orig = "ADD3" dest = "MQX"/>
</MED_Space>
<TRX_Record xmlns:ns2 = "http://services.xxx.com/MED/v1.2" xmlns:ns4 = "http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns3 = "http://services.xxx.com/POQ_Header/v01">
<TRX_ID FILCreate = "2018-04-17T03:59:00-05:00" resID = "1">TFRSVL</TRX_ID>
<Space>
<Inds revenue = "1"/>
<Identification nameID = "1" dHS_ID = "TFRSVL001" gender = "X">
<Name_First>SMITH MR</Name_First>
<Name_Last>P584ER</Name_Last>
<TT tier = "0"/>
</Identification>
<TRXType>F</TRXType>
<SRiuyx>0</SRiuyx>
<GroupRes>1</GroupRes>
<SystemInstances inventory = "H">Y</SystemInstances>
<OandD_FIL orig = "ADD3" dest = "MQX"/>
<Store = "584">0108</Store>
<CodingSpec = "584">0108</CodingSpec>
</Space>
</TRX_Record>
<ns2:TRX_Count xmlns:ns2 = "http://services.xxx.com/MED/v1.2" xmlns:ns4 = "http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns3 = "http://services.xxx.com/POQ_Header/v01">1</ns2:TRX_Count>
<ns2:Transaction_D584ails xmlns:ns2 = "http://services.xxx.com/MED/v1.2" xmlns:ns4 = "http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns3 = "http://services.xxx.com/POQ_Header/v01" sourceID = "TPF">
<Client_Entry_Info authRSX = "54" agx = "S4" code = "ADD3">RESTORE AMEND:NEW-FIL/AFAX-UPDATED</Client_Entry_Info>
</ns2:Transaction_D584ails>
</MED:MED_PMT_Tmp_Notif>
2018-04-17 03:59:29,244 INFO [properties] (Thread-19) Updat584ype: PGML ; ProcessId: ##MISSING##
Запись ниже не возвращает весь текст: awk -v RS = '(^ | \ n) [0-9:, -] +' '/ TFRSVL / {print rs, $ 0} {rs = RT}' файл
Я думаю, что ожидаемый результат довольно ясен ... Я хотел бы получить всю строку, содержащую слово, которое я ищу, даже если есть строки разрыва, я подумал об использовании INFO | ERROR | TRACE в качестве разделителей или, возможно, даты так как мне тоже понадобится дата, но я не могу понять это. Записи sed, которые я пробовал, не работали :(
Если вы хотите найти строку и получить из нее всю строку, почему бы вам просто не использовать grep?
Я начал использовать grep, но он не работал в случае разрывов строк, он не возвращал весь текст. grep -A / B не вариант, потому что строки переменные.
Stack Overflow - это не сервис для написания кода. Пожалуйста, покажите свой код. Поскольку переполнение стека скрывает от вас причину закрытия: Вопросы, требующие помощи по отладке («почему этот код не работает?»), Должны включать в себя желаемое поведение, конкретную проблему или ошибку и кратчайший код, необходимый для их воспроизведения в самом вопросе. Вопросы без четкой постановки проблемы не будут полезны другим читателям. См .: Как создать минимальный, полный и проверяемый пример.
@jww, почему ты снова понижал каждый ответ? Вы пытаетесь преподать нам урок, что мы не должны отвечать на вопрос, если ваша светлость не одобрит вопрос?





с многосимвольным разделителем записей GNU awk
$ awk -v RS='(^|\n)[0-9 :,-]+' '/here/{print rs,$0} {rs=RT}' file
2018-04-18 03:48:07,043 ERROR [properties] (Thread-13) UpdateType: more data coming here; ProcessId: 5010
2018-04-17 13:22:24,230 INFO [log] I need to retrieve this string here
and also this one as it is part of the same text
NB Здесь я обманул, создав разделитель записей, который использует значения в метке времени. Вы можете точно сформулировать это, чтобы исключить ложные срабатывания, заканчивающиеся в начале второй строки. Или, возможно, также добавьте уровни отладки к совпадению.
это неплохо, но по какой-то причине я все еще получаю ошибки с исходным журналом. Редактирую описание.
Теперь это работает для меня. Я также удалил пробел в регулярном выражении «[0-9:, -]» (после 9), и он работает должным образом. Не могли бы вы помочь мне раскрасить шнурок? Я пытался включить в команду "\ 033 [32m", но я раскрашиваю весь текст или получаю фатальные ошибки.
Предположим, что каждая запись начинается с метки времени, затем строки, состоящей из букв верхнего регистра, а затем другой строки в квадратных скобках:
$ cat tst.awk
/^[0-9]{4}(-[0-9]{2}){2} [0-9]{2}(:[0-9]{2}){2},[0-9]{3} [[:upper:]]+ \[[^][]+\] / { prt() }
{ rec = (rec= = "" ? "" : rec ORS) $0 }
END { prt() }
function prt() {
if (rec ~ regexp) {
print rec
print "----"
}
rec = ""
}
$ awk -v regexp='here' -f tst.awk file
2018-04-18 03:48:07,043 ERROR [properties] (Thread-13) UpdateType: more data coming here; ProcessId: 5010
----
2018-04-17 13:22:24,230 INFO [log] I need to retrieve this string here
and also this one as it is part of the same text
----
Вы можете изменить начальное регулярное выражение на что-то другое, если это недостаточно строго, например если текст в записи заканчивается строкой, соответствующей тому же регулярному выражению, в начале следующей строки (хотя я не знаю, как вы на самом деле справитесь с этим, учитывая то, что вы нам показали до сих пор).
Также подумайте, что это делает:
$ cat tst.awk
/^[0-9]{4}(-[0-9]{2}){2} [0-9]{2}(:[0-9]{2}){2},[0-9]{3} [[:upper:]]+ \[[^][]+\] / { prt() }
{ rec = (rec= = "" ? "" : rec ORS) $0 }
END { prt() }
function prt( flds,recDate,recTime,recPrio,recType,recText) {
split(rec,flds)
recDate = flds[1]
recTime = flds[2]
recPrio = flds[3]
recType = flds[4]
gsub(/[][]/,"",recType)
recText = rec
sub(/([^[:space:]]+ ){4}/,"",recText)
gsub(/[[:space:]]+/," ",recText)
if (NR > 1) {
if ( date= = "" || date==recDate ) {
printf "date = <%s>\n", recDate
printf "time = <%s>\n", recTime
printf "prio = <%s>\n", recPrio
printf "type = <%s>\n", recType
printf "text = <%s>\n", recText
print "----"
}
}
rec = ""
}
.
$ awk -v date='2018-04-18' -f tst.awk file
date = <2018-04-18>
time = <03:48:07,043>
prio = <ERROR>
type = <properties>
text = <(Thread-13) UpdateType: more data coming here; ProcessId: 5010>
----
.
$ awk -f tst.awk file
date = <2018-04-17>
time = <03:59:29,243>
prio = <TRACE>
type = <xml>
text = <This is just a test.>
----
date = <2018-04-17>
time = <13:22:24,230>
prio = <INFO>
type = <properties>
text = <I believe this is another test.>
----
date = <2018-04-18>
time = <03:48:07,043>
prio = <ERROR>
type = <properties>
text = <(Thread-13) UpdateType: more data coming here; ProcessId: 5010>
----
date = <2018-04-17>
time = <13:22:24,230>
prio = <INFO>
type = <log>
text = <I need to retrieve this string here and also this one as it is part of the same text>
----
date = <2018-04-17>
time = <13:22:24,230>
prio = <INFO>
type = <det>
text = <I believe this is another test.>
----
и представьте, как с помощью этого подхода вы можете легко создавать точные запросы к определенным полям записей журнала, создавать CSV для импорта в Excel и т. д. и т. д.
результаты хорошие, все равно сделать это без создания файла tst.awk? Я спрашиваю, потому что мне нужно использовать SSH через разные серверы, и я не хочу создавать файл на каждом сервере.
Конечно. Просто используйте awk 'script' inputfile вместо awk -f scriptfile inputfile. См. Верхнюю часть страницы руководства awk.
Пожалуйста, будьте более ясны, ваш вопрос непонятен. Четко изложите ожидаемый образец вывода и покажите нам тоже вместе со своей попыткой.