“^ barra invertida não é o último caractere on line” em gawk

1

Gostaria de combinar um número entre / e , em cada linha e aumentá-lo por 3. Por exemplo

The Ubiquitous Backslash/49,Black

torna-se

The Ubiquitous Backslash/52,Black

Meu comando gawk é:

$ gawk '{b=gensub(/\/([0-9]+),/, "/" (\1+3) ",") ; print b}' add.jpdf 
gawk: cmd. line:1:                    ^ backslash not last character on line

Eu queria saber o que "^ barra invertida não último caractere on line" significa? Qual regra de sintaxe do gawk minha solução viola?

Obrigado.

    
por Tim 17.07.2017 / 18:19

1 resposta

5

gensub() espera uma string como segundo argumento. Você está tentando concatenar / e , em torno de uma expressão (\1+3) , que você supõe que será avaliada pela função. Não vai. É avaliado antes de chamar a função. Você usa para se referir ao grupo de captura correspondente () no regexp, mas só pode usá-lo em uma string, não em uma expressão.

Então, na melhor das hipóteses, você poderia usar como segundo argumento "/\1+3," , mas você obteria o resultado ...Backslash/49+3,Black . Você não pode avaliar a parte 49 + 3 desta maneira.

Se você quiser fazer aritmética na correspondência, você deve primeiro extrair a string, fazer a aritmética e depois colocá-la de volta na string. Por exemplo,

awk '{ n = split($0, d, /\/([0-9]+),/, s)
       print d[1] "/"(substr(s[1],2)+3)"," d[2] }'

Isso usa a função split() do gnu awk com um regexp para dividir a linha em três partes: a parte antes da correspondência em d[1] , a parte após a correspondência em d[2] e a string combinada "/49," em s [1]. Você deve realmente verificar n é 2 para garantir que você tenha exatamente uma correspondência.

Você pode então extrair o número da string combinada simplesmente pulando o "/" inicial, fazer a aritmética e concatenar todas as partes juntas novamente.

Se o padrão pode aparecer várias vezes em uma linha de seus dados, uma solução melhor é usar match() para encontrar apenas a última ocorrência e cortar a linha usando substr() :

awk '{ match($0, /.*\/([0-9]+),/, m)
       a = m[1,"start"]
       b = m[1,"length"]
       if(a)print substr($0,1,a-1) substr($0,a,b)+3 substr($0,a+b)
       else print }'

Aqui, o padrão tem .* adicionado na frente para corresponder apenas à última ocorrência. a está definido para a posição do caractere do início do grupo de captura () na regexp e b para seu comprimento, portanto, substr($0,a,b) é apenas o número. A linha final é remontada das duas outras partes dos dados originais.

    
por 17.07.2017 / 19:04

Tags