Como usar o argumento de linha de comando como expressão correspondente ao regex awk?

2

Eu tenho o seguinte script awk:

#!/bin/awk -f

BEGIN {
    FS  = "";
}

value ~ "MYVALUE" # silly test
{
    print "1 - " substr($0, 235, 12);
}

$235 ~ "M" {
    print "2 - " substr($0, 235, 12);
}

{
    if(value == substr($0, 235, 12))
    {
        print "3 - " substr($0, 235, 12);
    }
    if(match(value,substr($0, 235, 12)))
    {
        print "4 - " substr($0, 235, 12);
    }
}

END {
    print "exit"
}

Eu corro como: ./script.awk -v value="MYVALUE" my_file

Este é o awk do meu RHEL 5.5:

$ ls -l  $(which awk)
lrwxrwxrwx 1 root root 4 Jul 10  2015 /bin/awk -> gawk
$ gawk --version
GNU Awk 3.1.5

1 e 2 trabalho. Como um aparte, se, em 2, eu coloco o { em uma nova linha, como:

$235 ~ "M" 
{
    print "2 - " substr($0, 235, 12);
}

a saída é a linha completa correspondente, não apenas a impressão.

O que eu gostaria de fazer é usar value para corresponder a uma expressão regular, mas ela sempre falha. Algo como:

$235...$247 ~ value

Eu vi exemplos ([ 1831722 ] [ unix / 27410 ]) de combinar um único caractere, mas não uma expressão.

EDITAR

Para maior clareza, quero corresponder as linhas que não possuem separador de campo, usando um parâmetro de linha de comando passado para o awk e usando-o em um deslocamento de vários caracteres da linha. Eu hackeei alguns python:

#!/usr/bin/python

import re

t   = 'ABC'
rg  = '^.{235,235}' + t
rgx = re.compile(rg)
tt  = '00000ABC00'
if(rgx.match(tt)):
    print "OK"
else:
    print "KO"

Somente para este caso de uso o awk provavelmente seria mais rápido, já que os arquivos em questão são bem grandes.

    
por vesperto 24.02.2017 / 14:44

2 respostas

0

Isso parece funcionar.

{
    if(substr($0, 235, 12) ~ value)
    {
        print "4 - " substr($0, 235, 12)
        next
    }
    else
    {
        print "4 - NOK"
        next
    }
}
    
por 24.02.2017 / 14:52
0

Eu sei que isso é um pouco antigo, mas eu pensei em adicionar alguns comentários se alguém mais acabar aqui. Em primeiro lugar, para criar um intervalo de campos, você pode separá-los com , , então

$235, $247 ~ value { ... action here ... }

A saída da função substr também pode ser usada diretamente para tentar encontrar uma correspondência, se desejado:

substr($0, 235, 12) ~ value { ... action here ... }

Além disso, parece que você descobriu que a colocação de algumas das chaves é importante. Com cada correspondência, o par de ações, a correspondência ou a ação pode ser um padrão implícito (corresponder a todos ou imprimir $ 0), portanto, a alteração de

$235 ~ "M" {  print "2 - " substr($0, 235, 12);  }

para

$235 ~ "M" 
{  print "2 - " substr($0, 235, 12);  }

altera o significado de print this substring only when field 235 is an M para whenever field 235 is an M print the whole record, AND for every record, print the substring . então, isso poderia ser usado se, por exemplo, você precisasse executar várias verificações na subseqüência de cada registro, sua primeira ação poderia ser:

BEGIN { FS="" }
# oursubstr will be updated first for each record.
{ oursubstr = substr($0, 235, 12) } 
oursubstr ~ value { ... action ... }
...
    
por 17.01.2018 / 18:50