Encontré algunas formas de pasar variables de shell externas a un awk
script, pero estoy confundido acerca de '
y "
.
Primero, probé con un script de shell:
$ v=123test
$ echo $v
123test
$ echo "$v"
123test
Luego probé awk:
$ awk 'BEGIN{print "'$v'"}'
$ 123test
$ awk 'BEGIN{print '"$v"'}'
$ 123
¿Por qué es la diferencia?
Por último probé esto:
$ awk 'BEGIN{print " '$v' "}'
$ 123test
$ awk 'BEGIN{print ' "$v" '}'
awk: cmd. line:1: BEGIN{print
awk: cmd. line:1: ^ unexpected newline or end of string
Estoy confundido acerca de esto.
/var/
. En cambio, use tilde:awk -v var="$var" '$0 ~ var'
Respuestas:
Usando
-v
(La mejor manera, más portátil)Use la
-v
opción: (PS usa un espacio después-v
o será menos portátil. Por ejemplo,awk -v var=
noawk -vvar=
)Esto debería ser compatible con la mayoría
awk
, y la variable también está disponible en elBEGIN
bloque:Si tienes múltiples variables:
Advertencia . Como escribe Ed Morton, las secuencias de escape se interpretarán, por lo que se
\t
convierte en algo realtab
y no\t
si eso es lo que buscas. Se puede resolver mediante el usoENVIRON[]
o el acceso a través deARGV[]
PD: si le gustan tres barras verticales como separador
|||
, no se puede escapar, así que use-F"[|][|][|]"
Variable después del bloque de código
Aquí obtenemos la variable después del
awk
código. Esto funcionará bien siempre que no necesite la variable en elBEGIN
bloque:awk '{print a,b,$0}' a="$var1" b="$var2" file
FS
para cada archivo.awk 'some code' FS=',' file1.txt FS=';' file2.ext
BEGIN
bloque:echo "input data" | awk 'BEGIN {print var}' var="${variable}"
Here-string
La variable también se puede agregar al
awk
uso de una cadena aquí de los shells que los admiten (incluido Bash):Esto es lo mismo que:
PD: trata la variable como una entrada de archivo.
ENVIRON
entradaComo TrueY escribe, puede usar
ENVIRON
para imprimir Variables de entorno . Al configurar una variable antes de ejecutar AWK, puede imprimirla así:ARGV
entradaComo escribe Steven Penny, puede usar
ARGV
para obtener los datos en awk:Para obtener los datos en el propio código, no solo el COMIENZO:
Variable dentro del código: USO CON PRECAUCIÓN
Puede usar una variable dentro del
awk
código, pero es desordenada y difícil de leer, y comoCharles Duffy
señala, esta versión también puede ser víctima de la inyección de código. Si alguien agrega cosas malas a la variable, se ejecutará como parte delawk
código.Esto funciona extrayendo la variable dentro del código, por lo que se convierte en parte de él.
Si desea hacer un
awk
cambio dinámico con el uso de variables, puede hacerlo de esta manera, pero NO lo use para variables normales.Aquí hay un ejemplo de inyección de código:
Puede agregar muchos comandos de
awk
esta manera. Incluso haz que se bloquee con comandos no válidos.Información extra:
Uso de comillas dobles
Siempre es bueno comillas dobles.
"$variable"
Si no, se agregarán varias líneas como una sola línea larga.
Ejemplo:
Otros errores que puede obtener sin comillas dobles:
Y con comillas simples, no expande el valor de la variable:
Más información sobre AWK y variables
Lee este faq .
fuente
awk -v repo="$1" -v tag="$2" 'BEGIN {print "repo="repo,"tag="tag}'
. Verá si imprime la variable. Publique una pregunta propia si no puede resolverlo.Parece que la buena vieja
ENVIRON
awkel hash incorporado no se menciona en absoluto. Un ejemplo de su uso:fuente
-v
no funciona cuando el valor contiene barras invertidas.awk -v x='\c\d' ...
, lo usaré correctamente. Pero cuandox
se imprime awk cae el famoso:awk: warning: escape sequence '\c' treated as plain 'c'
mensaje de error ... ¡Gracias!-v
fue diseñado para funcionar para que pueda usar\t
en la variable y hacer que coincida con una pestaña literal en los datos, por ejemplo. Si ese no es el comportamiento que desea, entonces no lo use-v
, useARGV[]
oENVIRON[]
.Utilice cualquiera de estos dependiendo de cómo desee barras invertidas en las variables de shell manejadas (
avar
es una variable awk,svar
es una variable de shell):Consulte http://cfajohnson.com/shell/cus-faq-2.html#Q24 para obtener detalles y otras opciones. El primer método anterior es casi siempre su mejor opción y tiene la semántica más obvia.
fuente
Puede pasar la opción de línea de comandos
-v
con un nombre de variable (v
) y un valor (=
) de la variable de entorno ("${v}"
):O para hacerlo más claro (con muchos menos
v
s):fuente
Puede utilizar ARGV:
Tenga en cuenta que si va a continuar dentro del cuerpo, deberá ajustar ARGC:
fuente
Acabo de cambiar la respuesta de @ Jotne para "for loop".
fuente
-v
opción de Awk que ya se mencionó en muchas de las respuestas existentes. Si desea mostrar cómo ejecutar Awk en un bucle, esa es una pregunta realmente diferente.Tuve que insertar la fecha al comienzo de las líneas de un archivo de registro y se hace de la siguiente manera:
Se puede redirigir a otro archivo para guardar
fuente