Возврат строк в параметрах sed / grep / awk / gawk

Нужна помощь, чтобы вернуть все данные в файл журнала с двумя определенными разделителями. Обычно у нас есть журналы, подобные приведенному ниже:

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}' файл

Пожалуйста, будьте более ясны, ваш вопрос непонятен. Четко изложите ожидаемый образец вывода и покажите нам тоже вместе со своей попыткой.

RavinderSingh13 03.05.2018 17:11

Я думаю, что ожидаемый результат довольно ясен ... Я хотел бы получить всю строку, содержащую слово, которое я ищу, даже если есть строки разрыва, я подумал об использовании INFO | ERROR | TRACE в качестве разделителей или, возможно, даты так как мне тоже понадобится дата, но я не могу понять это. Записи sed, которые я пробовал, не работали :(

TerminatorX 03.05.2018 17:18

Если вы хотите найти строку и получить из нее всю строку, почему бы вам просто не использовать grep?

RavinderSingh13 03.05.2018 17:19

Я начал использовать grep, но он не работал в случае разрывов строк, он не возвращал весь текст. grep -A / B не вариант, потому что строки переменные.

TerminatorX 03.05.2018 17:28

Stack Overflow - это не сервис для написания кода. Пожалуйста, покажите свой код. Поскольку переполнение стека скрывает от вас причину закрытия: Вопросы, требующие помощи по отладке («почему этот код не работает?»), Должны включать в себя желаемое поведение, конкретную проблему или ошибку и кратчайший код, необходимый для их воспроизведения в самом вопросе. Вопросы без четкой постановки проблемы не будут полезны другим читателям. См .: Как создать минимальный, полный и проверяемый пример.

jww 04.05.2018 03:46

@jww, почему ты снова понижал каждый ответ? Вы пытаетесь преподать нам урок, что мы не должны отвечать на вопрос, если ваша светлость не одобрит вопрос?

Ed Morton 04.05.2018 15:31
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
6
104
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

с многосимвольным разделителем записей 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 Здесь я обманул, создав разделитель записей, который использует значения в метке времени. Вы можете точно сформулировать это, чтобы исключить ложные срабатывания, заканчивающиеся в начале второй строки. Или, возможно, также добавьте уровни отладки к совпадению.

это неплохо, но по какой-то причине я все еще получаю ошибки с исходным журналом. Редактирую описание.

TerminatorX 03.05.2018 18:11

Теперь это работает для меня. Я также удалил пробел в регулярном выражении «[0-9:, -]» (после 9), и он работает должным образом. Не могли бы вы помочь мне раскрасить шнурок? Я пытался включить в команду "\ 033 [32m", но я раскрашиваю весь текст или получаю фатальные ошибки.

TerminatorX 08.05.2018 16:12

Предположим, что каждая запись начинается с метки времени, затем строки, состоящей из букв верхнего регистра, а затем другой строки в квадратных скобках:

$ 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 через разные серверы, и я не хочу создавать файл на каждом сервере.

TerminatorX 03.05.2018 18:22

Конечно. Просто используйте awk 'script' inputfile вместо awk -f scriptfile inputfile. См. Верхнюю часть страницы руководства awk.

Ed Morton 03.05.2018 21:31

Другие вопросы по теме