У меня есть текстовый файл, похожий на этот
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 значения после метки времени, это не работает правильно.
Также, пожалуйста, добавьте, почему строки 00:00:26.792
, затем 0
и т. д. отсутствуют в ожидаемом результате, пожалуйста, отредактируйте свой вопрос один раз.
@ RavinderSingh13 это нежелательный результат, поскольку они не предлагают дополнительной информации.
Тогда, пожалуйста, упомяните также логику удаления его из ожидаемого вывода?
@ RavinderSingh13 Я не очень понимаю, что вы здесь говорите. Логика удаления его из ожидаемого вывода заключается в том, что они не предлагают дополнительную информацию, как я сказал выше. Мне нужно только сохранить строки, которые имеют хотя бы одно значение полученного/отправленного трафика. Тем не менее спасибо за ваше время в попытке помочь мне.
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. Таким образом, приведенный выше скрипт в основном буферизует строки между двумя временными метками, и если они соответствуют критериям, согласно которым после временной метки должно быть как минимум две строки, и они не должны быть равны нулю, печатает их.
если у вас есть время, пожалуйста, объясните это кратко.
Это может сработать для вас (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
Результаты с желаемым результатом.
я пробовал подобные вещи для
awk -F, 'length($1) < 8 { print f; print;getline;print} {f=$1}'
, поэтому он печатал временную метку вместе со следующими двумя строками. Но поскольку файл несовместим, он не работает должным образом.