AWK combina expressão variável e regular em correspondência de padrão

4

Estou procurando pesquisar em um arquivo por uma coluna com 3 letras, seguida de 3 ou 4 numerais. eg.
if ( $1 ~ /^[A-Z][A-Z][A-Z][0-9][0-9][0-9]/)
No entanto, eu preciso das 3 letras para ser uma variável, então estou procurando o resultado de SP="ABC" if ( $1 ~ /^/SP/[0-9][0-9][0-9]/)
No entanto, isso não funciona e não encontrei uma maneira de combinar uma variável e uma expressão regular no padrão de pesquisa. Qualquer ajuda muito apreciada.

    
por Carlos 25.01.2016 / 20:58

2 respostas

5
SP="ABC" 
if ( $1 ~ "^" SP "[0-9]{3}")

Você pode concatenar strings , mas não /xxx/ s, que são mais semelhantes aos operadores de correspondência de expressões regulares, e com regras de análise que podem ser confusas (e variar entre implementações)

$1 ~ /ABC/ /BCD/

pode ser visto como a concatenação de $1 correspondida à concatenação de /ABC/ (1 ou 0 dependendo se $0 corresponde a /ABC/ ) e /BCD/ (1 ou 0 dependendo se $0 corresponde a /BCD/ ) ou $1 correspondido a /ABC/ (0 ou 1) concatenado com $0 correspondido a /BCD/ , o que seria confuso o suficiente, exceto que o operador /regexp/ não funciona bem quando combinado com alguns outros gostam do operador de concatenação aqui, pois há uma possível confusão com o operador / division.

Mas com parênteses, você pode obter comportamentos interessantes (leia buggy ):

$ echo 11 ab | gawk '{print $1 ~ /a/ (/b/)}'
1
$ echo 11 ab | bwk-awk '{print $1 ~ /a/ (/b/)}'
01
$ echo b | bwk-awk '{print /a/ - (/b/)}'
0-1

(este último sendo o resultado de /a/ (0) concatenado com o resultado de - (/b/) ).

observe que, em $1 =~ "^" SP "[0-9]{3}" , o conteúdo do SP ainda é tratado como um regexp (se for ... , que corresponde a 3 caracteres, não a 3 pontos); se isso não é desejado:

if (index($1, SP) == 1 && substr($1, length(SP)+1) ~ /^[0-9]{3}/)
    
por 25.01.2016 / 22:34
2

Você pode dizer ao awk para ler expressões regulares começando com caracteres exatos, e depois com um caractere "tipo" entre colchetes, seguido pelo número de repetições entre chaves. Assim:

echo "ABC956" |  awk '{ if( $1 ~ /^ABC[0-9]{3}/) print "HELLOWORLD" }'                                 
HELLOWORLD

Você pode usar o operador lógico && para testar a presença da variável e da expressão regular também

echo "ABC956" |  awk -v VAR="ABC" '{ if( $1 ~ VAR && $1 ~ /[0-9]{3}/) print "HELLOWORLD" }'            
HELLOWORLD
    
por 25.01.2016 / 21:10

Tags