Grep com alcance e passe três filtros

2

Eu tenho um arquivo sample.txt

-------------
ord:chandru  SAM 
    XY       DUPL
    KEY:ZZ
-------------
ord:RAM      SAM 
    XY       DUPL
    KEY:UU
-------------
ord:chandru  SAM 
    XY       DUPL
    KEY:ZZ
-------------

em que estou filtrando pedidos com base em palavras-chave como ord:chandru e key:ZZ , se encontrar essas ocorrências, removerei os pedidos de hífen para hífen para gerar uma saída como essa

-------------
ord:chandru  SAM 
    XY       DUPL
    KEY:ZZ
-------------
ord:chandru  SAM 
    XY       DUPL
    KEY:ZZ
-------------
    
por chandu 24.02.2017 / 15:16

4 respostas

3

Se você tem o GNU awk , eu sugeriria algo assim:

gawk 'BEGIN{RS="-+\n"} $0=="" || /ord:chandru/ && /KEY:ZZ/ {ORS=RT; print}' sample.txt
-------------
ord:chandru  SAM 
    XY       DUPL
    KEY:ZZ
-------------
ord:chandru  SAM 
    XY       DUPL
    KEY:ZZ
-------------

O $0=="" apenas força a impressão de registros vazios (que é como a primeira linha do arquivo será interpretada, se você considerar que os registros serão delimitados por strings de hifens).

Se você não tem gawk , então a única diferença é que você não pode capturar facilmente o separador de registro - na amostra que você forneceu, isso não é um grande problema, já que é uma string fixa. Por exemplo, com mawk :

mawk 'BEGIN{RS="-------------\n"; ORS=RS} $0=="" || /ord:chandru/ && /KEY:ZZ/ {print}' sample.txt
-------------
ord:chandru  SAM 
    XY       DUPL
    KEY:ZZ
-------------
ord:chandru  SAM 
    XY       DUPL
    KEY:ZZ
-------------
    
por 24.02.2017 / 16:02
1

Isso deve ser bastante confiável

$ sed -n '1p; /ord:chandru/ {             
N                                           
N
/KEY:ZZ/{
N
/ord:chandru.*\n.*\n.*KEY:ZZ.*\n---.*/p
}
}' file

Explicação

  • -n não imprime até pedirmos algo
  • 1p imprime a primeira linha, supondo que nos dará uma linha de hifens (depois, imprimimos apenas linhas de hifens)
  • /ord:chandru/ encontra o padrão
  • N leu a próxima linha para nos permitir usar o caractere \n para representar novas linhas
  • p imprime as linhas correspondentes
por 24.02.2017 / 15:50
0

Usando o awk :

$ awk 'BEGIN{RS="-------------"};/KEY:ZZ/&&/ord:chandru/{print RS$0}' sample.txt|egrep -v "^ *$"

Saída:

-------------
ord:chandru  SAM 
    XY       DUPL
    KEY:Z    
-------------
ord:chandru  SAM 
    XY       DUPL
    KEY:ZZ
    
por 24.02.2017 / 16:09
0
sed -e '
   /^ord:/,/^--*$/!b
   H; /^ord:/h
   /^--*$/!d; g
   /^ord:chandru[ ]/!d
   /\n[ ]*KEY:ZZ\n--*$/!d
'  sample.txt

Resumo breve:    /../,/../ = > é o operador de intervalo para selecionar um intervalo de linhas, como no seu caso de /ord:/ to /----/ .

Nós esquecemos balançar estes intervalos (um intervalo de cada vez) para a área de espera. Então, quando estamos no final do intervalo /---/ , sabemos que chegou a hora de selecionar ou rejeitar esse intervalo específico com base nos critérios que 'a) / ord: chandru / & & b) / chave: ZZ / '

    
por 25.02.2017 / 03:35