Удаление блоков кода, которые удовлетворяют условию - PullRequest
0 голосов
/ 12 апреля 2019

У меня очень большой текстовый файл, который в основном представляет собой журнал сообщений с { в качестве разделителя между сообщениями. Я хочу удалить блоки между {, если они удовлетворяют определенному условию. В приведенном ниже примере я хочу удалить средний блок сообщений с EVENT_TYPE = BDE и оставить два ABC сообщения. Файл находится на коробке Linux, поэтому у меня есть доступ ко всем вашим обычным grep, sed, awk и т. Д. Я могу использовать эти процессы, чтобы найти EVENT_TYPE, но не уверен, как затем найти больший блок и удалить его ,

}
/type/ - DataEvents = {
VALUE = 2342
EVENT_TYPE = ABC
VALUE_YESTERDAY = 1299
HAS_DELAY = false
SEND_TIME_RT = 18:55:21.224+00:00
} 

/type/ - DataEvents = {
VALUE = 889
EVENT_TYPE = BDE
VALUE_YESTERDAY = 778 
HAS_DELAY = false
SEND_TIME_RT = 18:55:21.224+00:00
} 

/type/ - DataEvents = {
VALUE = 123
EVENT_TYPE = ABC
VALUE_YESTERDAY = 345
HAS_DELAY = false
SEND_TIME_RT = 18:55:21.224+00:00
} 

Ответы [ 6 ]

3 голосов
/ 12 апреля 2019

Всякий раз, когда входные данные имеют пары имя = значение, я считаю наиболее удобным / надежным / поддерживаемым / расширяемым сначала создать массив (f[] ниже) этого сопоставления для каждой записи (rec ниже), а затем получить доступ к значениям по именам для тестирования, печати и т. д .:

$ cat tst.awk
BEGIN { FS=" *= *" }
NF { rec = rec $0 ORS; f[$1] = $2 }
/^}/ {
    if ( f["EVENT_TYPE"] != "BDE" ) {
        print rec
    }
    rec = ""
    delete f
}

$ awk -f tst.awk file
/type/ - DataEvents = {
VALUE = 2342
EVENT_TYPE = ABC
VALUE_YESTERDAY = 1299
HAS_DELAY = false
SEND_TIME_RT = 18:55:21.224+00:00
}

/type/ - DataEvents = {
VALUE = 123
EVENT_TYPE = ABC
VALUE_YESTERDAY = 345
HAS_DELAY = false
SEND_TIME_RT = 18:55:21.224+00:00
}
1 голос
/ 12 апреля 2019

Это может работать для вас (GNU sed):

sed '/{/{:a;N;/}/!ba;/EVENT_TYPE = BDE/d}' file

Соберите строки между { и } и, если эти строки содержат EVENT_TYPE = BDE, удалите их.

0 голосов
/ 12 апреля 2019

если ваши данные в 'd' от gnu sed

sed -Ez 's/\{[^{}]*EVENT_TYPE\s*=\s*BDE[^}]*\}//' d
0 голосов
/ 12 апреля 2019

Как насчет

$ vim -es '+g/EVENT_TYPE = BDE/exe "norm! dap"' '+%print' '+q!' file

Вывод:

}
/type/ - DataEvents = {
VALUE = 2342
EVENT_TYPE = ABC
VALUE_YESTERDAY = 1299
HAS_DELAY = false
SEND_TIME_RT = 18:55:21.224+00:00
}

/type/ - DataEvents = {
VALUE = 123
EVENT_TYPE = ABC
VALUE_YESTERDAY = 345
HAS_DELAY = false
SEND_TIME_RT = 18:55:21.224+00:00
}
0 голосов
/ 12 апреля 2019

Не могли бы вы попробовать следующее.

awk '
/{/{
  val=""
}
/}/{
  if(found=="" && val){
     print val ORS $0
  }
  found=val=""
  next
}
/EVENT_TYPE = BDE/{
  found=1
}
{
  val=(val?val ORS:"")$0
}
END{
  if(val && found==""){
    print val ORS $0
  }
}
'   Input_file
0 голосов
/ 12 апреля 2019

Используя gawk для многосимвольного RS, вы можете настроить RS так, чтобы каждый блок обрабатывался как отдельная запись, а затем просто проверяйте в пределах записи, как обычно.Мы используем NR > 1, чтобы игнорировать нежелательную первую (пустую) запись, которая возникает из данных, начинающихся с разделителя записей (при условии, что это не ясно из вашей частичной выборки).

$ gawk -v RS='/type/' 'NR > 1 && !/EVENT_TYPE = BDE/ { printf "/type/%s", $0 }' file
/type/ - DataEvents = {
VALUE = 2342
EVENT_TYPE = ABC
VALUE_YESTERDAY = 1299
HAS_DELAY = false
SEND_TIME_RT = 18:55:21.224+00:00
}

/type/ - DataEvents = {
VALUE = 123
EVENT_TYPE = ABC
VALUE_YESTERDAY = 345
HAS_DELAY = false
SEND_TIME_RT = 18:55:21.224+00:00
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...