r4 - 02 Jul 2009 - RonaldoLima
NOME
a2p - Awk to PerlSINOPSE
a2p [opções] [arquivo]DESCRIÇÃO
A2p lê um script awk especificado na linha de comando (ou a partir da entrada padrão) e produz um script perl comparável, na saída padrão.OPÇÕES
Opções incluem:- -D<number>
- seta flags de debug.
- -F<character>
- Diz ao a2p que este script awk é sempre invocado com a opção -F
- -n<fieldlist>
- Especifica o nome dos campos de entrada se a entrada não necessitar ser dividade em um array.
- Se você estava traduzindo um script awk que processa arquivos de password, você deve escrever:
-
a2p -7 -nlogin.password.uid.gid.gcos.shell.home - Qualquer delimitador pode ser usado para separar o nome dos campos.
- -<number>
- Com isso, a2p assume que a entrada sempre terá este número de campos.
- -o
- Diz ao a2p para usar o velho comportamento de awk. As diferenças atuais são:
-
O velho awk sempre tem um loop de linha, mesmo que não haja ações na linha, enquanto o novo awk não faz isso.
No velho awk, sprintf é extremamente apetitoso quanto aos seus argumentos.
Por exemplo, dada a instrução:
print sprintf(some_args), extra_args;
O awk velho considera que extra_args são argumentos para sprintf; O novo awk considera eles argumentos para print.
Considerações
a2p não pode fazer um trabalho de tradução tão bom quanto um humano poderia, mas ele normalmente faz muito bem. Existem algumas áreas em que você talvez queira examinar o script perl produzido, e ajustá-lo um pouco. Aqui estão algumas delas, sem nenhuma ordem em particular. Existe um idioma awk de colocarint() ao redor de strings para forçar a interpretação
numérica, mesmo que o argumento seja sempre um inteiro. Isto normalmente é
desnecessário em perl, mas a2p não tem como saber se o argumento será sempre
inteiro, então ele o mantém. Talvez você queira removê-lo.
Perl diferencia comparações numéricas de comparações literais. Awk tem um único
operador para ambos que decide em tempo de execução que tipo de comparação fazer.
A2p não tenta fazer um trabalho completo de emular awk nesse ponto. Ao invés disso,
ele adivinha qual deles você quer. Ele acerta quase sempre, mas pode se enganar. Todas
estas adivinhações são marcadas com o comentário ``#???''. Você deveria ir direto
neles e verificá-los. Você também pode rodar perl pelo menos uma vez com a chave
-w, que irá avisá-lo se você usou ``=='' quando deveria usar ``eq''.
Perl não tenta emular o comportamento de awk no qual arrays com elementos não existentes
passam a existir simplesmente por terem sido referenciados. Se de alguma forma, você está
contando com isso como um mecanismo para criar entradas nulas para um for...in subsequente,
eles não estarão lá em Perl.
Se a2p cria um linha de divisão que cria uma lista de variáveis que parecem com
(Fld1, Fld2, Fld3...) você talvez queria re-executar a2p usando a opção -n
mencionada acima. Isso vai deixar você nomear os campos pelo script.
Se em vez disso, dividir em um array, o script provavelmente está se
referindo ao número de campos em algum lugar.
A instrução exit em awk não necessariamente sai do script e sim vai até um bloco END, se houver um.
Scripts awk que fazem contorcionismos com o bloco END para desviarem sob certas circunstâncias podem
ser simplificados removendo a instrução condicional no bloco END e simplesmente saindo diretamente
pelo script Perl.
Perl tem dois tipos de array, indexados numericamente e associativos.
Os arrays associativos de Perl são chamados hashes. Arrays awk são
comumente traduzidos para hashes, mas se acontecer de você saber que
o índice vai ser sempre numérico, você pode alterar o {...} para [...].
Iteração sobre um hash é feita usando a função keys(), mas iteração
sobre um array NÃO é. Você vai precisar modificar qualquer loop que itera
por arrays.
Awk começa assumindo que OFMT tem o valor %.6g. Perl começa assumindo
seu equivalente, $#, tendo valor %.20g. Você vai querer modificar $# explicitamente
se você usa o valor padrão do OFMT.
Perto do topo do loop de linha vai estar a operação de divisão que é implícita
nos scripts awk. Haverá situações que você poderá mover isso para baixo seguindo
algumas condições que testam a gravação inteira de modo que a divisão não seja feita
como frequentemente é feita.
Por razões estéticas, você talvez deseje mudar a base do array $[ de 1
de volta para o padrão Perl que é 0, mas lembre-se de mudar todos os índices de arrays
E todas as operações como substr() e index() para acharem os índices corretamente.
Comentários bonitinhos que dizem ``# Aqui está uma gambiarra, pois awk é burro''
passarão sem modificações.
Scripts awk são frequentemente embutidos em shell scripts que redireciona sua saída
para dentro e para fora do awk. Quase sempre o shell script wrapper pode ser
incorporado ao script perl, já que perl pode iniciar redirecionamentos para dentro e para fora
de si mesmo, e pode fazer outras coisas que awk não pode fazer sozinho.
Scripts que referenciam a variáveis especiais como RSTAR e RLENGTH podem ser
simplificados constantemente simplesmente referenciando-os às variáveis $`, $& e $',
contanto que eles estejam dentro do escopo do padrão que devem estar.
O script perl produzido talvez tenha subrotinas definidas para lidar com a semântica
awk, considerando getline e print. Tendo em vista que a2p comumente
escolhe exatidão do que eficiência. Quase sempre é possível re-escrever tal código para
ser mais eficiente descartando essa semântica café-com-leite.
Para eficiência, você pode querer remover a palavra-chave de todos as instruções return
que é a última instrução executada numa subrotina. A2p pega o caso mais comum, mas não
analisa blocos embutidos de casos mais sutis.
ARGV[0] traduz para $ARGV0, mas ARGV[n] traduz para $ARGV[$n]. Um loop que tente
iterar sobre ARGV[0] não irá achar isso.

