Por que uma expressão regular constante não pode ser colocada no lado esquerdo de um operador ~ no gawk?

5

Por que não posso colocar uma expressão regular no lado esquerdo do operador ~ ao usar o gawk?

Por exemplo, dado o arquivo abaixo com campos delimitados por tabulações (\ t):

$ cat cats
siberian    1970    73  2500
shorthair   1999    60  3000
longhair    1998    102 9859
scottish    2001    30  6000

Se eu usar o gawk para encontrar um registro, ele funciona:

$ gawk '$1 ~ /h/' cats
shorthair   1999    60  3000
longhair    1998    102 9859
scottish    2001    30  6000

No entanto, se eu mover os operandos $ 1 e / h / ao redor, isso não acontece:

$ gawk '/h/ ~ $1' cats
gawk: cmd. line:1: warning: regular expression on left of '~' or '!~' operator

A página de manual do gawk para o operador ~ diz:

Regular expression match, negated match. NOTE: Do not use a constant regular expression (/foo/) on the left-hand side of a ~ or !~. Only use one on the right-hand side. The expression /foo/ ~ exp has the same meaning as (($0 ~ /foo/) ~ exp). This is usually not what was intended.

Eu não entendo como a expressão / foo / é avaliada para se tornar ($ 0 ~ / foo /) e isso também parece implicar apenas a frase mais fraca "coisas ruins acontecerão se você colocar uma expressão regular constante à esquerda "na verdade não implica a frase mais strong de" o comportamento do gawk é indefinido se você colocar uma expressão regular constante à esquerda porque não foi programado para ser usado dessa maneira ".

Eu basicamente não entendo como o operador ~ é avaliado internamente.

    
por Jerry Marbas 15.06.2015 / 23:29

1 resposta

8

Para citar a especificação POSIX para o awk:

When an ERE token appears as an expression in any context other than as the right-hand of the ~ or !~ operator or as one of the built-in function arguments described below, the value of the resulting expression shall be the equivalent of:

$0 ~ /ere/

Isso (combinado com o padrão de ação para { print } ) é por que você pode usar awk como um grep substituto apenas fazendo awk '/b/' <file .

Então, a resposta é apenas "está definido para funcionar dessa maneira". /ere/ é definido para significar $0 ~ /ere/ , exceto em determinadas circunstâncias, e /ere/ ~ $1 não é uma das circunstâncias excepcionais, por isso é avaliado como ($0 ~ /ere/) ~ $1 .

    
por 16.06.2015 / 00:16

Tags