Как удалить строки после первой проверки следующих 3 строк

У меня есть текстовый файл, похожий на этот

00:00:24.752
8,594
3,847
0
00:00:25.228
0
1,692
0
00:00:25.738
6,548
5,304
0
00:00:26.248
1,807
417
0
00:00:26.758
3,913
5,335
0
00:00:26.792
0
00:00:27.234
0
00:00:27.268
0
0
0
00:00:27.778
9,903
2,345
0
00:00:27.812
0
00:00:28.322
0
9,501
0

это сетевой трафик, и первая часть представляет собой метку времени, а следующие две части — это отправленный и полученный трафик. Третий - это ноль, который я не знаю, почему там.
Итак, моя цель — сохранить только те строки, которые имеют хотя бы значение отправленного/полученного трафика, а также каждый раз удалять третий 0. Так что у меня будет такой результат.

00:00:24.752
8,594
3,847
00:00:25.228
0
1,692
00:00:25.738
6,548
5,304
00:00:26.248
1,807
417
00:00:26.758
3,913
5,335
00:00:27.778
9,903
2,345
00:00:28.322
0
9,501

Пробовали использовать awk в смысле проверки длины текущей строки, и если строка меньше 8 символов, то напечатайте эту строку и следующие 2. Но поскольку файл не всегда имеет как минимум 2 значения после метки времени, это не работает правильно.

я пробовал подобные вещи для awk -F, 'length($1) < 8 { print f; print;getline;print} {f=$1}', поэтому он печатал временную метку вместе со следующими двумя строками. Но поскольку файл несовместим, он не работает должным образом.

kampias 17.05.2019 13:02

Также, пожалуйста, добавьте, почему строки 00:00:26.792, затем 0 и т. д. отсутствуют в ожидаемом результате, пожалуйста, отредактируйте свой вопрос один раз.

RavinderSingh13 17.05.2019 13:03

@ RavinderSingh13 это нежелательный результат, поскольку они не предлагают дополнительной информации.

kampias 17.05.2019 13:17

Тогда, пожалуйста, упомяните также логику удаления его из ожидаемого вывода?

RavinderSingh13 17.05.2019 13:27

@ RavinderSingh13 Я не очень понимаю, что вы здесь говорите. Логика удаления его из ожидаемого вывода заключается в том, что они не предлагают дополнительную информацию, как я сказал выше. Мне нужно только сохранить строки, которые имеют хотя бы одно значение полученного/отправленного трафика. Тем не менее спасибо за ваше время в попытке помочь мне.

kampias 17.05.2019 13:31
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
66
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий
awk '
/[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}/ {
  if (NR > 1) p() 
  i = 0
}
{ buf[++i] = $0 }
END { p() }
function p() {
  if (buf[2] || buf[3]) {
    print buf[1]
    print buf[2]
    print buf[3]
  }
  delete buf
}' file

p — это функция, которая печатает строки из буфера, если 2-я и 3-я из них не пусты или не равны нулю, и очищает буфер. Он вызывается всякий раз, когда видна временная метка (и это не первая строка в файле) и когда нажимается EOF. Таким образом, приведенный выше скрипт в основном буферизует строки между двумя временными метками, и если они соответствуют критериям, согласно которым после временной метки должно быть как минимум две строки, и они не должны быть равны нулю, печатает их.

если у вас есть время, пожалуйста, объясните это кратко.

kampias 17.05.2019 13:26

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

sed '/:/!{H;$!d};x;/\n.*\n.*\n/{/\n0\n0\n0/!s/\n0$//p};x;h;d' file

Если текущая строка не является временной меткой (не содержит :), добавьте ее в пробел, а если это не последняя строка, удалите ее.

Если текущая строка является либо последней строкой, либо отметкой времени, переключитесь на пространство хранения и убедитесь, что предыдущая запись содержит 4 строки и что последние 3 строки не обнулены, если это так, удалите последнюю строку записи и распечатайте измененная запись.

Вернитесь к пространству шаблона, замените пространство удержания текущей строкой (меткой времени) и удалите ее.

Н.Б. Когда строка удаляется, дальнейшая обработка sed для текущей строки не выполняется.

Если вы хотите опустить все 4-е строки, для этого используйте скрипт awk:

awk 'RN % 4{print}' input.txt

Результаты с желаемым результатом.

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