Como imprimir seu próprio nome de script no mawk?

13

No bash $0 contém o nome do script, mas no awk se eu criar um script chamado myscript.awk com o seguinte conteúdo:

#!/usr/bin/awk -f
BEGIN{ print ARGV[0] }

e execute-o, ele só imprimirá "awk". Além disso, ARGV [i] com i > 0 é usado apenas para argumentos de script na linha de comando. Então, como fazer com que seja impresso o nome do script, neste caso "myscript.awk"?

    
por cipper 07.09.2015 / 17:10

5 respostas

5

Com o GNU awk 4.1.3 no bash no cygwin:

$ cat tst.sh
#!/bin/awk -f
BEGIN { print "Executing:", ENVIRON["_"] }

$ ./tst.sh
Executing: ./tst.sh

Eu não sei quão portável isso é. Como sempre, no entanto, eu não executaria um script awk usando um shebang em um shell script, já que ele apenas rouba uma possível funcionalidade. Mantenha a simplicidade e faça isso:

$ cat tst2.sh
awk -v cmd="$0" '
BEGIN { print "Executing:", cmd }
' "$@"

$ ./tst2.sh
Executing: ./tst2.sh

Esse último vai funcionar com qualquer awk moderno em qualquer shell em qualquer plataforma.

    
por 08.09.2015 / 16:16
5

Não creio que isso seja possível, de acordo com a documentação de gawk :

Finally, the value of ARGV[0] (see section 7.5 Built-in Variables) varies depending upon your operating system. Some systems put awk there, some put the full pathname of awk (such as /bin/awk), and some put the name of your script ('advice'). Don't rely on the value of ARGV[0] to provide your script name.

Em linux , você pode tentar usar uma espécie de hack sujo e, como apontam os comentários de Stéphane Chazelas é possível se a implementação de awk suportar bytes NUL:

#!/usr/bin/awk -f

BEGIN { getline t < "/proc/self/cmdline"; split(t, a, "
#!/usr/bin/awk -f

BEGIN { getline t < "/proc/self/cmdline"; split(t, a, "%pre%"); print a[3]; }
"); print a[3]; }
    
por 07.09.2015 / 18:22
5

Eu não conheço nenhuma maneira direta de obter o nome do comando de dentro do awk. Você pode, no entanto, encontrá-lo através de uma sub-casca.

gawk

Com o GNU awk e o comando ps , é possível usar o ID do processo de PROCINFO["PID"] para recuperar o nome do comando como uma solução alternativa. Por exemplo:

cmdname.awk

#!/usr/bin/gawk -f

BEGIN {
  ("ps -p " PROCINFO["pid"] " -o comm=") | getline CMDNAME
  print CMDNAME
}

mawk e nawk

Você pode usar a mesma abordagem, mas derivar o PID de awk da variável de shell especial $PPID (PID do pai):

cmdname.awk

#!/usr/bin/mawk -f

BEGIN { 
  ("ps -p $PPID -o comm=") | getline CMDNAME
  print CMDNAME
}

Teste

Execute o script assim:

./cmdname.awk

Saída nos dois casos:

cmdname.awk
    
por 07.09.2015 / 18:23
4

Com POSIX awk :

#!/usr/bin/awk -f

BEGIN {
    print ENVIRON["AWKSCRIPT"]
}

Então:

AWKSCRIPT=test.awk ./test.awk
test.awk
    
por 07.09.2015 / 18:31
4

Usando o GNU awk

Verificando o guia do usuário do GNU awk - 7.5.2 Variáveis integradas que transmitem informações Eu tropecei em:

PROCINFO #

The elements of this array provide access to information about the running awk program. The following elements (listed alphabetically) are guaranteed to be available:

PROCINFO["pid"]

The process ID of the current process.

Isso significa que você pode conhecer o PID do programa durante o tempo de execução. Então, é uma questão de usar system() para procurar o processo com este PID:

#!/usr/bin/gawk -f
BEGIN{ pid=PROCINFO["pid"]
       system("ps -ef | awk '$2==" pid " {print $NF}'")
}

Eu uso ps -ef , que exibe o PID na segunda coluna. Assumindo que a execução é feita através de awk -f <script> e nenhum outro parâmetro, podemos assumir que o último campo da linha contém as informações que desejamos.

No caso de termos alguns parâmetros, teríamos que analisar a linha de maneira diferente - ou melhor, usar algumas das opções de ps para imprimir apenas as colunas em que estamos interessados.

Teste

$ awk -f a.awk 
a.awk
$ cp a.awk hello.awk
$ awk -f hello.awk 
hello.awk

Note também que outro capítulo do guia do usuário do GNU awk nos diz que o ARGV não é o caminho a seguir:

1.1.4 Executable awk Programs

Finally, the value of ARGV[0] (see Built-in Variables) varies depending upon your operating system. Some systems put ‘awk’ there, some put the full pathname of awk (such as /bin/awk), and some put the name of your script (‘advice’). (d.c.) Don’t rely on the value of ARGV[0] to provide your script name.

    
por 08.09.2015 / 00:18