¿Hay 2 formas de configurar awk vars a través de la línea de comandos?


10

Noté un awkejemplo de O'Reilly (1997) que asignaba una variable awk configurándola en la línea de comando después del texto del programa. Funciona, pero no puedo encontrar esta sintaxis en man / info awk . ¿Lo acabo de perder? ¿está depricated ...? La única sintaxis que he visto en el manual es la -vopción.

awk '/home/{print foo, bar}' foo="cat" bar="dog" /proc/$$/cmdline

Salida: cat dog

Respuestas:


11

En realidad está en POSIX awk(enlace a POSIX 2008, las versiones anteriores también lo tenían, creo). -vse describe en la sección Opciones , la otra forma está en la sección Operandos .

Hay una diferencia entre -vy pasar las tareas al final con los nombres de archivo:

  • Con -v:

La aplicación garantizará que el argumento de asignación tenga la misma forma que un operando de asignación. La asignación de la variable especificada debe ocurrir antes de ejecutar el programa awk, incluidas las acciones asociadas con los patrones BEGIN (si corresponde). Se pueden especificar múltiples ocurrencias de esta opción.

  • Mezclado con los nombres de archivo:

[...] Cada asignación variable de este tipo debe ocurrir justo antes del procesamiento del siguiente archivo , si corresponde. Por lo tanto, una asignación antes del primer argumento del archivo se ejecutará después de las acciones BEGIN (si corresponde), mientras que una asignación después del último argumento del archivo ocurrirá antes de las acciones END (si corresponde). Si no hay argumentos de archivo, las asignaciones se ejecutarán antes de procesar la entrada estándar.

Ejemplo:

$ cat input 
hello
hello
$ awk -v var=one 'BEGIN{print var} /hello/{print var} END{print var}' \
    var=two input var=three input var=four
one
two
two
three
three
four

¡Guauu! Eso agrega algunos puntos de control interesantes ... seguramente será útil. Gracias ...
Peter.O

1
Mi inicial "¡Guau!" todavía se mantiene, pero se ha atenuado un poco al analizar la respuesta de Arcege ... Lo probé con un archivo real llamado "var = three" ... awkle dio prioridad a que fuera una asignación variable ... Esto tiene un corolario importante es decir En todos los casos cuando un nombre de archivo tiene esta forma, se ignorará y se establecerá la variable ... Parece que la única forma de evitar este choque es asegurando que los nombres de archivo para el directorio de trabajo actual siempre tengan el prefijo con su camino relativo:./var=three
Peter.O

@ Peter.O, sí, esa es también una de las razones por las que -vse introdujo la sintaxis. Debería pensar en la -vsintaxis como la forma preferida de hacer tareas en el futuro.
dubiousjim

@ Peter.O, excelente punto sobre el "problema" si un nombre de archivo es una asignación de variable válida. Si está utilizando una variable de shell que contiene un nombre de archivo y se la pasa como argumento awk, puede usar el siguiente mensaje:[ "$myfile" == "${myfile#/}" ] && myfile="./$myfile"
Comodín el

4

Este es un estilo antiguo de configuración de variables externas awk. Era ambiguo (¿y si tuviera un nombre de archivo con nombre? foo=cat), Por lo que las versiones posteriores agregaron una -vopción. Probablemente debería funcionar para la compatibilidad con versiones anteriores, pero no puede garantizarlo. Y como dije, la -vopción es más nueva, por lo que no todas las versiones awkpueden admitirla.


Su comentario sobre la posibilidad de un choque de nombre de archivo es bueno ... Lo he probado y definitivamente es un problema. He escrito un poco más sobre esto en un comentario a la respuesta de Mat. Thansk por resaltar este problema (+1)
Peter.O

2
En realidad, como se explica en [Mat s answer](http://unix.stackexchange.com/a/34258/9537), -v` y la asignación de argumentos son diferentes cuando entran en vigencia. También -vestá en POSIX y debería estar presente en todas las awkimplementaciones, excepto en las más antiguas . Usar ./o asegurarse de que el nombre del archivo contenga un carácter no identificador es probablemente la forma más confiable de desambiguar.
jw013
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.