Imprimir correspondência e linha após

6

Eu tenho alguns dados em que a quarta coluna será frz ou - . Eu gostaria de encontrar todas as linhas onde a quarta coluna é frz somente se a quarta coluna na próxima linha for - e, em seguida, imprimir ambas as linhas.

Exemplo de entrada:

2018-04-09T14:15:23.366Z  7 multi -   uuid1 uuid2 uuid3 -
2018-04-09T14:15:23.978Z  8 multi frz   uuid1 uuid3 -        -
2018-04-09T14:29:35.826Z  8 multi frz   uuid1 uuid3 uuid2 -
2018-04-09T17:19:01.901Z  8 multi frz uuid1 uuid3 uuid2 -
2018-06-03T22:12:38.688Z  8 multi -   uuid1 uuid3 uuid2 -
2018-06-28T00:35:54.338Z  9 multi -   uuid1 uuid2 -        -
2018-06-28T00:47:51.679Z  9 multi -   uuid1 uuid2 uuid3 -
2018-06-28T00:47:51.720Z 10 multi -   uuid1 uuid3 -        -
2018-06-28T00:47:58.863Z 10 multi -   uuid1 uuid3 uuid2 -
2018-06-28T16:29:01.624Z 10 multi frz uuid1 uuid3 uuid2 -
2018-06-28T17:29:01.624Z 10 multi - uuid1 uuid3 uuid2 -

Resultado esperado:

2018-04-09T17:19:01.901Z  8 multi frz uuid1 uuid3 uuid2 -
2018-06-03T22:12:38.688Z  8 multi -   uuid1 uuid3 uuid2 -
2018-06-28T16:29:01.624Z 10 multi frz uuid1 uuid3 uuid2 -
2018-06-28T17:29:01.624Z 10 multi - uuid1 uuid3 uuid2 -

Encontrei alguns comandos awk para imprimir a linha depois de uma partida, mas não consigo descobrir como combinar as duas linhas e imprimir ambas.

O que eu tenho atualmente:

$ awk 'f{print;f=0} $4=="frz"{f=1}' input
2018-04-09T14:29:35.826Z  8 multi frz   uuid1 uuid3 uuid2 -
2018-04-09T17:19:01.901Z  8 multi frz uuid1 uuid3 uuid2 -
2018-06-03T22:12:38.688Z  8 multi -   uuid1 uuid3 uuid2 -
2018-06-28T17:29:01.624Z 10 multi - uuid1 uuid3 uuid2 -
    
por Jesse_b 28.06.2018 / 19:16

4 respostas

5

Que tal:

awk '$4=="-" && prev4=="frz" {print prevline; print} {prev4 = $4; prevline=$0}' file
    
por 28.06.2018 / 19:34
4

Se você tem o GNU grep e seu padrão não ocorre em nenhum outro lugar nos dados, você pode tentar isto:

grep -A1 frz | grep -vB1 frz

Explicação

O primeiro grep captura todas as linhas em que o padrão ocorre, mais o próximo:

-A NUM, --after-context=NUM Print NUM lines of trailing context after matching lines. Places a line containing a group separator (--) between contiguous groups of matches.

A saída deste primeiro comando na sua entrada de amostra é:

2018-04-09T14:15:23.978Z  8 multi frz   uuid1 uuid3 -        -
2018-04-09T14:29:35.826Z  8 multi frz   uuid1 uuid3 uuid2 -
2018-04-09T17:19:01.901Z  8 multi frz uuid1 uuid3 uuid2 -
2018-06-03T22:12:38.688Z  8 multi -   uuid1 uuid3 uuid2 -
--
2018-06-28T16:29:01.624Z 10 multi frz uuid1 uuid3 uuid2 -
2018-06-28T17:29:01.624Z 10 multi - uuid1 uuid3 uuid2 -

Em seguida, o segundo comando procura linhas não contendo o padrão e as imprime com a linha antes:

-B NUM, --before-context=NUM Print NUM lines of leading context before matching lines. Places a line containing a group separator (--) between contiguous groups of matches.

Como observado na página man do grep , a saída contém separadores de grupos ( -- ):

2018-04-09T17:19:01.901Z  8 multi frz uuid1 uuid3 uuid2 -
2018-06-03T22:12:38.688Z  8 multi -   uuid1 uuid3 uuid2 -
--
2018-06-28T16:29:01.624Z 10 multi frz uuid1 uuid3 uuid2 -
2018-06-28T17:29:01.624Z 10 multi - uuid1 uuid3 uuid2 -

Você pode adicionar um terceiro grep para removê-los, se necessário:

grep -A1 frz | grep -vB1 frz | grep -v '^--$'
    
por 28.06.2018 / 21:07
3

Eu gostaria de oferecer uma abordagem completamente impraticável do GNU grep . Funciona, mas parece desagradável.

grep -Pzo "^\S+\s+\S+\s+\S+\s+frz\s+.*\n\S+\s+\S+\s\S+\s+\-\s+.*" input

Exemplo.

$ cat file
2018-04-09T14:15:23.366Z  7 multi -   uuid1 uuid2 uuid3 -
2018-04-09T14:15:23.978Z  8 multi frz   uuid1 uuid3 -        -
2018-04-09T14:29:35.826Z  8 multi frz   uuid1 uuid3 uuid2 -
2018-04-09T17:19:01.901Z  8 multi frz uuid1 uuid3 uuid2 -
2018-06-03T22:12:38.688Z  8 multi -   uuid1 uuid3 uuid2 -
2018-06-28T00:35:54.338Z  9 multi -   uuid1 uuid2 -        -
2018-06-28T00:47:51.679Z  9 multi -   uuid1 uuid2 uuid3 -
2018-06-28T00:47:51.720Z 10 multi -   uuid1 uuid3 -        -
2018-06-28T00:47:58.863Z 10 multi -   uuid1 uuid3 uuid2 -
2018-06-28T16:29:01.624Z 10 multi frz uuid1 uuid3 uuid2 -
2018-06-28T17:29:01.624Z 10 multi - uuid1 uuid3 uuid2 -
$ grep -Pzo "^\S+\s+\S+\s+\S+\s+frz\s+.*\n\S+\s+\S+\s\S+\s+\-\s+.*" file
2018-04-09T17:19:01.901Z  8 multi frz uuid1 uuid3 uuid2 -
2018-06-03T22:12:38.688Z  8 multi -   uuid1 uuid3 uuid2 -
2018-06-28T16:29:01.624Z 10 multi frz uuid1 uuid3 uuid2 -
2018-06-28T17:29:01.624Z 10 multi - uuid1 uuid3 uuid2 -
$ grep -V 2>&1|head -1
grep (GNU grep) 2.20
$
    
por 28.06.2018 / 20:41
1

Você pode tentar este sed também

sed -E '
  /([^ ]* *){3}frz .*/!d
  $!N
  /(.*\n)([^ ]* *){3}- .*/!D
' infile
    
por 28.06.2018 / 23:16