variable script externas define bash shell awk

bash - externas - ¿Cómo uso las variables de shell en un script awk?



bash script (8)

Acabo de cambiar la respuesta de @ Jotne por "for loop".

for i in `seq 11 20`; do host myserver-$i | awk -v i="$i" ''{print "myserver-"i" " $4}''; done

Encontré algunas formas de pasar variables de shell externas a un script awk , pero estoy confundido acerca de '' y " .

Primero, lo intenté con un script de shell:

$ v=123test $ echo $v 123test $ echo "$v" 123test

Entonces intentó awk:

$ awk ''BEGIN{print "''$v''"}'' $ 123test $ awk ''BEGIN{print ''"$v"''}'' $ 123

¿Por qué es la diferencia?

Por último he intentado 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.


Obtener variables de shell en awk puede hacerse de varias maneras. Algunos son mejores que otros.

Esta es la mejor manera de hacerlo. Utiliza la opción -v : (PS usa un espacio después de -v o será menos portátil. Por ejemplo, awk -v var= not awk -vvar= )

variable="line one/nline two" awk -v var="$variable" ''BEGIN {print var}'' line one line two

Esto debería ser compatible con la mayoría de los awk y la variable también está disponible en el bloque BEGIN :

Variables multiples

awk -v a="$var1" -v b="$var2" ''BEGIN {print a,b}''

Aquí obtenemos la variable después del código awk . Esto funcionará bien siempre y cuando no necesite la variable en el bloque BEGIN :

variable="line one/nline two" echo "input data" | awk ''{print var}'' var="$variable" or awk ''{print var}'' var="$variable" file

Esto también funciona con múltiples variables awk ''{print a,b,$0}'' a="$var1" b="$var2" file

La variable también se puede agregar a awk usando la cadena aquí

awk ''{print $0}'' <<< "$variable" test

Esto es lo mismo que:

echo "$variable" | awk ''{print $0}''

PD, esto amenaza la variable como entrada de archivo.

Como TrueY write, puede utilizar el MEDIO AMBIENTE para imprimir Environmental Variables establecer una variable antes de ejecutar AWK, puede imprimirla de la siguiente manera:

X=MyVar awk ''BEGIN{print ENVIRON["X"],ENVIRON["SHELL"]}'' MyVar /bin/bash

Editar: Como escribe "ese otro chico", esto no se ocupa de la barra invertida. No recomendado.

Puede usar una variable dentro del código awk , pero es complicado y difícil de leer, y como señala Charles Duffy , esta versión también puede ser una víctima de la inyección de código. Si alguien agrega cosas malas a la variable, se ejecutará como parte del código awk .

Si desea hacer un awk que cambie dinámicamente con el uso de variables, puede hacerlo de esta manera, el bot NO lo use para variables normales.

variable="line one/nline two" awk ''BEGIN {print "''"$variable"''"}'' line one line two

Aquí hay un ejemplo de inyección de código:

variable=''line one/nline two" ; for (i=1;i<=1000;++i) print i"'' awk ''BEGIN {print "''"$variable"''"}'' line one line two 1 2 3 . . 1000

Puedes agregar muchos comandos a awk esta manera. Incluso hacer que se bloquee con comandos no válidos.

Siempre es bueno hacer doble comillas variable "$variable"
Si no, se agregarán múltiples líneas como una sola línea larga.

Ejemplo:

var="Line one This is line two" echo $var Line one This is line two echo "$var" Line one This is line two

Otros errores que puede obtener sin comillas dobles:

variable="line one/nline two" awk -v var=$variable ''BEGIN {print var}'' awk: cmd. line:1: one/nline awk: cmd. line:1: ^ backslash not last character on line awk: cmd. line:1: one/nline awk: cmd. line:1: ^ syntax error

Y con comillas simples, no amplía el valor de la variable:

awk -v var=''$variable'' ''BEGIN {print var}'' $variable


Parece que el hash incorporado de ENVIRON awk no se menciona en absoluto. Un ejemplo de su uso:

$ X=Solaris awk ''BEGIN{print ENVIRON["X"], ENVIRON["TERM"]}'' Solaris rxvt


Podría 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}" ):

% awk -vv="${v}" ''BEGIN { print v }'' 123test

O para hacerlo más claro (con muchos menos v s):

% environment_variable=123test % awk -vawk_variable="${environment_variable}" ''BEGIN { print awk_variable }'' 123test


Puede utilizar ARGV:

v=123test awk ''BEGIN {print ARGV[1]}'' "$v"

Tenga en cuenta que si va a continuar con el cuerpo, deberá ajustar ARGC:

awk ''BEGIN {ARGC--} {print ARGV[2], $0}'' file "$v"


Tuve que insertar la fecha al comienzo de las líneas de un archivo de registro y se hace como a continuación:

DATE=$(date +"%Y-%m-%d") awk ''{ print "''"$DATE"''", $0; }'' /path_to_log_file/log_file.log

Puede ser redirigido a otro archivo para guardar


Utilice cualquiera de estos dependiendo de cómo quiera que se manejen las barras invertidas en las variables de shell ( avar es una variable awk, svar es una variable de shell):

awk -v avar="$svar" ''... avar ...'' file awk ''BEGIN{avar=ARGV[1];ARGV[1]=""}... avar ...'' "$svar" file

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.


for i in chr{1..22} chrX chrY do awk -v chr="$i" ''$1==chr'' ../snp150.hg19.txt >> $chr.vcf.bed echo $i done