Como as barras invertidas são processadas com sucesso por bash, gawk e gensub ()?

2

Eu tenho um arquivo

$ cat f2
line 1; li
ne 2$

onde observe que o último $ é o prompt do bash, e não parte do conteúdo do arquivo.

Eu tento concatenar cada linha que não termina em um dígito com sua próxima linha com gawk . Mas ao contrário do meu post anterior, agora tento descobrir como as barras invertidas são manipuladas por bash, gawk e gensub (), experimentando um número diferente de barras invertidas na frente do novo caractere de linha \n . Eu estava me perguntando por que o gawk comanda com mais de três barras invertidas antes de n falhar em encontrar uma linha que não termina em um dígito, e ter sucesso em caso contrário? Geralmente, como as barras invertidas são processadas com sucesso por bash, gawk e gensub ()? Obrigado.

$ gawk 'BEGIN{RS="\f"} {b=gensub("([^[:digit:] ]) *\n", "\1", "g"); print b}' f2
line 1; line 2
$ gawk 'BEGIN{RS="\f"} {b=gensub("([^[:digit:] ]) *\n", "\1", "g"); print b}' f2
line 1; line 2
$ gawk 'BEGIN{RS="\f"} {b=gensub("([^[:digit:] ]) *\\n", "\1", "g"); print b}' f2
line 1; line 2
$ gawk 'BEGIN{RS="\f"} {b=gensub("([^[:digit:] ]) *\\n", "\1", "g"); print b}' f2
line 1; li
ne 2

Alguém pode explicar o que gawk e gensub () veem quando \n , \n , \\n e \\n passam por bash e gawk respectivamente?

Tome \n como exemplo, o bash não o modifica (por causa das aspas simples no bash), então o gawk vê \n ? O gawk modifica \n para ser n , então gensub () vê n , e se sim, por que gensub () sabe que é uma nova linha para combinar?

    
por Tim 14.11.2018 / 04:44

1 resposta

2

Em bash , '...' são aspas strongs, então com '\n' , um literal \n é passado para awk e com '\n' , um literal \n . Não há transformação.

Em awk , dentro de "..." , \n e \ ... são expandidos. Assim, quando passado "\n" a gensub() (ou print ou qualquer coisa em awk ), esse é um caractere de nova linha real e, quando passado "\" , é \ .

Agora, gensub() também entende seu primeiro argumento como uma expressão regular, em que \ também tem um significado especial que varia entre as implementações.

O que é consistente entre as implementações é que \ regexp corresponde a um literal \ , assim como \. corresponde a um literal . . No entanto, para um \n regexp, se isso corresponde a um caractere de nova linha ou a n varia com a implementação. No caso de gawk , que corresponde à nova linha. Portanto, gensub("\n", "x") e gensub("\n", "x") substituem caracteres de nova linha por x , o primeiro porque um caractere literal de nova linha é passado para gensub() , o segundo porque \n é passado para gensub() , que é entendido como um regexp que corresponde a um caractere de nova linha.

Observe que a especificação POSIX costumava ter vários problemas quando se tratava de processamento de contrabarra em expressões regulares em awk . Isso será corrigido na próxima versão da especificação. Consulte o link para obter detalhes.

Fica ainda mais confuso ao usar /\n/ em vez de "\n" .

    
por 14.11.2018 / 17:23

Tags