Como fazer a busca de padrões de múltiplas linhas usando o awk no unix?

2

Eu tenho que procurar por um padrão de várias linhas no meu script sql usando awk .

Exemplo de script -

select * from dept where department_name in ('abc'
, 'xyz', 'def') ;

No exemplo acima, tenho que pesquisar o padrão department_name in até o colchete de fechamento ) e pode haver várias ocorrências desse padrão no script.

Os valores na cláusula 'IN' abrangerão várias linhas no exemplo acima.

    
por Pankaj Pandey 10.02.2017 / 07:55

3 respostas

3

Supondo que o SQL use ; como delimitadores de instrução:

$ cat statements.sql
First bit;
Second thing;

More
of the same;

select * from dept where department_name in ('abc'
, 'xyz', 'def') ;

Getting to the end;

The
End;

Em seguida, você pode usar ; como o separador de registro em awk e combinar como de costume:

$ awk 'BEGIN { RS=";" } /department_name in ([^)]+)/ { print $0 ";" }' statements.sql


select * from dept where department_name in ('abc'
, 'xyz', 'def') ;

O padrão, /department_name in ([^)]+)/ corresponde à string department_name in ( seguido por um ou vários caracteres que não são ) (incluindo novas linhas), seguidos por um único ) .

A instrução print adiciona ; ao final do registro, já que ; foi removido por awk (remove todos os separadores de registro).

Você obterá algumas linhas em branco extras, já que havia linhas em branco após o ; precedente no arquivo. Você pode filtrá-los com sed -n '/[[:graph:]]/p' :

$ awk 'BEGIN {RS=";"} /department_name in ([^)]+)/ { print $0 ";" }' statements.sql |
  sed -n '/[[:graph:]]/p'
select * from dept where department_name in ('abc'
, 'xyz', 'def') ;
    
por 10.02.2017 / 09:04
2

Você pode usar awk e o separador de registro RS :

$ cat << EOT | awk -v RS="department_name|)" 'NR%2==0'
> select * from dept where department_name in ('abc' , 
> 'xyz', 
> 'def') ;
> EOT
in ('abc' , 
'xyz', 
'def'

RS está definido como department_name ou ) , assim o registro pode ser composto por várias linhas.

Desde que você não tenha duas vezes a mesma tag, NR%2=0 imprimirá tudo entre as duas tags diferentes.

    
por 10.02.2017 / 08:22
0

Espero que esta seja a resposta que você procura:

grep -oE 'department_name.*\)' file_name

O P.S não conhece a solução do awk para isso.

    
por 10.02.2017 / 08:13

Tags