Я пытаюсь удалить сообщения об ошибках, распечатанные в мой файл. У меня есть это:
addr:1122c:1234:
addr:11230:5678:
addr:11223:01Error:abcdef(x, y) = z, value = a
Error:hijklm(v, q) = w, value = b
Error:nopqrst(x, y) = z, value = d
Error:uvwxyz(l, m) = z, value = e
Error:1234(u, t) = z, value = f
Error:567(r, s) = z, value = g
err_total = 9846, err_sub = 0, err_mask = 239
1 Duration: xyz, abc
0 Duration: pqr, def
23:
addr:11238:4567:
addr:1123c:8901:
Я должен удалить все сообщения об ошибках до следующего addr, появляется. Необходимый вывод:
addr:1122c:1234:
addr:11230:5678:
addr:11223:0123:
addr:11238:4567:
addr:1123c:8901:
Я попробовал:
sed -i "/\bError\b/d" file_name
Но это удаляет строки, начинающие с Ошибки, и не удалило строку где Строка ошибки, запущенная с середины.
Я плохо знаком с регулярными выражениями, explaination был бы действительно полезен.
Править: Я использую sed -i '/Error/,/addr/d' filename
но это удаляет целую строку и не дает то, что я ищу.
sed
не действительно хорошо в Многострочном Соответствии.
Можно обмануть его, чтобы сделать то, что Вы хотите, но затем imo perl
легче обработать.
Попробуйте это:
perl -pe 'BEGIN{undef $/;}; s/Error.*?(^[0-9]* Duration: [^\n]*\n)+//smg;'
Объяснение:
BEGIN { do_something; }
: Сделайте что-то однажды вначалеundef $/
: Проигнорируйте окончания строкиs///
ЗаменаError.*
Соответствуйте любой строке, начинающейся с "Ошибки".?
Сделайте предыдущее соответствие нежадным, для которого оно останавливается в следующем соответствии или в этой группе соответствия случая...()+
Сделайте группу соответствия, которая должна быть подобрана, по крайней мере, однажды (+
).^[0-9]* Duration: [^\n]*\n
: Соответствуйте целой строке Продолжительности включительноЭто сгенерирует результат, который вы искали:
$ cat file_name | grep -v \
-e '^Error:' \
-e '^err_total' \
-e '^.*[0-9] Duration:' | \
sed ':a;$!N;s/Error:.*\n\(.*[0-9]\):/\1:/;ta;P;D'
Frist удалите все вещи Error
, err_total
и 12345 Duration:
. Затем найдите Error: ...
, прерывающий ваш вывод, удалите новую строку (\n
), найдите следующий вхождение числа (.*[0-9]:
) и добавьте его к текущей строке.
Вместо того, чтобы удалять"Error:
"строки, почему бы не извлечь просто строки Вы хотите с:
grep -E '^ addr:' file_name | sed -e 's/Error:.*//'