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