Procura entre dois padrões e imprime os dados do primeiro padrão para o segundo padrão várias vezes, excluindo os blocos não correspondentes

4

Eu tenho que procurar por uma string específica na ordem inversa e imprimi-la.

No exemplo abaixo, quero pesquisar a partir do padrão not in order até o padrão number of .

Exemplo: o arquivo de entrada contém:

number of characters a[1] 
reg1 
reg2 
reg3 
info a[1] is not in order

number of characters a[3] 
reg1 
reg2 
reg3 
info a[3] is in order


number of characters a[2] 
reg1 
reg2 
reg3 
info a[2] is not in order

a saída deve ser:

number of characters a[1]
reg1 
reg2 
reg3 
info a[1] is not in order

number of characters a[2] 
reg1 
reg2 
reg3 
info a[2] is not in order
    
por Bhargavi Bk 23.08.2017 / 10:25

4 respostas

4

Usando in order com uma nova linha como delimitador de parágrafo, podemos fazer:

awk -v RS='in order\n' '/not/{print $0 "in order"}'

awk trata o texto separado pelo padrão em RS (separador de registro) como registros e cada operação é feita em um registro. Portanto, /not/ testa se o registro corresponde a not e, em seguida, imprimimos o registro ( $0 ) juntamente com o texto separador, que foi removido por awk.

Então:

$ mawk -v RS='in order\n' '/not/{print $0 "in order"}' foo
number of characters a[1]
reg1
reg2
reg3
info a[1] is not in order


number of characters a[2]
reg1
reg2
reg3
info a[2] is not in order
    
por muru 23.08.2017 / 10:43
3

Se os blocos tiverem que terminar com uma linha que contenha is in order ou is not in order , podemos excluir itens entre eles ...

$ sed '/is not in order/,/is in order/ {/is not in order/n;d}' file
number of characters a[1] 
reg1 
reg2 
reg3 
info a[1] is not in order


number of characters a[2] 
reg1 
reg2 
reg3 
info a[2] is not in order

Notas:

  • /is not in order/,/is in order/ encontra as linhas entre is not in order e is in order , inclusive
  • {some commands} agrupa estes comandos
  • /is not in order/n pula a linha com este padrão a partir do próximo comando
  • d exclua as linhas especificadas

Pode parecer complicado para encontrar a linha e, em seguida, encontrá-la novamente para ignorá-la, mas não podemos usar uma linha vazia, ou sed ativará sua sinalização operar aqui em a próxima linha vazia e continue até o próximo is in order , que excluirá muito.

    
por Zanna 23.08.2017 / 11:05
3

outra abordagem:

tac file | awk ' BEGIN {weprint=0 ; rem="not necessary, but for clarity"}
  /is not in order$/ { weprint=1 ;}
  ( weprint == 1)    { print $0  ;   rem="same remark here..."; }
  /^number of/       { weprint=0 ;}
' | tac

que pode ser encurtado se necessário ...

Se você quiser a linha separadora: altere a última linha como

"/^number of/" { print ; weprint=0;}
    
por Olivier Dulac 23.08.2017 / 11:35
2
perl -00 -ne 'print if /not in order/' file

A opção -00 lê o arquivo por parágrafos.
O -n adiciona um loop implícito sobre todos os parágrafos no arquivo.
Em seguida, imprima o parágrafo se ele contiver o texto desejado "não em ordem".

    
por glenn jackman 23.08.2017 / 14:10