Как исключить совпавший образец в файле и строках выше и ниже его? - PullRequest
0 голосов
/ 19 декабря 2018

Я хочу напечатать строки, содержащие Result: False и три строки над ним, кроме случаев, когда одна из трех строк содержит service.dead.

Так для следующего файла:

      ID: service1
Function: module.run
    Name: ps.kill_pid
  Result: True
 Comment: State was not run because onfail req did not change
 Started: 16:37:23.237741
Duration: 0.0 ms

      ID: service2
Function: service.dead
    Name: SomeService
  Result: False
 Comment: check_cmd determined the state failed
 Started: 16:37:23.567741
Duration: 8286.0 ms

      ID: service3
Function: service.running
    Name: SomeService
  Result: True
 Comment: Started Service SomeService
          Delayed return for 5 seconds
 Started: 16:38:22.956741
Duration: 47438.0 ms

      ID: check_status
Function: cmd.run
    Name: http.query http://1.1.1.1 
  Result: False
 Comment: Attempt 1: Returned a result of "False"
          Attempt 2: Returned a result of "False"
          Command "http.query http://1.1.1.1"
 Started: 16:40:57.424741
Duration: 50180.0 ms

Я хочу напечатать только

ID: check_status
Function: cmd.run
    Name: http.query http://1.1.1.1 
  Result: False

Мне удалось напечатать три строки выше Result: False и удалить две строки ниже service.dead с помощью следующей команды:

grep -B 3 'Result: False' /my/file | sed '/service.dead/,+2d'

Но я могуне можете найти, как удалить строку выше service.dead.Мой текущий вывод:

      ID: Service2
---
      ID: check_status
Function: cmd.run
    Name: http.query http://1.1.1.1 
  Result: False

Какой-нибудь элегантный способ сделать это?

Ответы [ 2 ]

0 голосов
/ 20 декабря 2018

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

sed -n ':a;N;s/\n/&/3;Ta;/service\.dead/ID;/Result:\s*False[^\n]*$/Ip;D' file

Используйте параметр -n, чтобы отключить автоматическую печать.Откройте окно из четырех строк по всей длине файла.Если какая-либо из четырех строк, содержащихся в пространстве шаблона, содержит текст service.dead, удалите первую и добавьте другую.Если последняя из четырех строк в пространстве образца заканчивается на Result: False, выведите пространство образца.Независимо от предыдущего результата, удалите первый и добавьте следующий, сохраняя окно из четырех строк.

0 голосов
/ 19 декабря 2018

Вы можете использовать awk:

awk '
    BEGIN {
        RS = ""
        FS = OFS = "\n"
    }
    $4 ~ /Result: False/ && !($2 ~ /service\.dead/) {
        print $1, $2, $3, $4
    }
' infile

Это делает следующее:

  • устанавливает разделитель записей RS на пустую строку, которая сообщает awk, что записи разделеныпустыми строками
  • поля разделяются символами новой строки как для ввода (FS), так и для вывода (OFS)
  • для каждой записи, мы сравниваем поля 4 и 2 с требуемыми значениями ивыведите первые четыре поля, если совпадение сработало
...