Llamar a programas externos desde awk [Solucionado]
Hola,
¿Alguien sabe cómo llamar desde una orden de awk a un programa externo? Me explico:
Tengo un fichero que tiene una pinta tal que:
BLG_ 1564 259200. 5569885.5340 3105318.5555 -180595.2185
BLG_ 1564 259500. 5569885.5341 3105318.5373 -180595.2038
La primera columna es el código de punto, la segunda la semana GPS, la tercera el segundo de la semana GPS y las tres últimas son coordenadas. Quiero convertir este fichero en:
BLG_ 2009.994520548 5569885.5340 3105318.5555 -180595.2185
BLG_ 2009.994530061 5569885.5341 3105318.5373 -180595.2038
donde se ha convertido la semana y el segundo de la semana en formato año.decimal_de_año. Tengo un programa en C para llamar desde la línea de órdenes y convertir la semana y el segundo a año.decimal. Ahora bien, ¿cómo puedo llamarlo desde awk?
Estoy intentando hacerlo con system:
cat fichOrig | awk '{print $1,system("programa "$2 $3),$4,$5,$6}'
pero me da error.
¿Alguien tiene alguna idea?
- Inicie sesión o regístrese para enviar comentarios
- 846 lecturas


mmmh... no lo pillo.. ¿cuando dices llamar te refieres a abrirlo o a cambiarle el nombre simplemente? en el segundo caso ¿para que necesitas cat?
Y luego está system... ¿te has asegurado de que te devuelve siempre el valor correcto y no "false" por ejemplo?
Cat te da los parametros necesarios para que se ejecute la linea awk... no entiendo bien lo que quieres hacer, asi como lo has puesto funciona... aunque podrias probar anteponiendo exec a programa, podrias mostrarnos el error?
Cat lo uso para leer el fichero original y pasarle los datos a awk.
Cuando digo llamar me refiero a ejecutar el programa que convierte semana y segundo en año.decimal, para insertarlo en la salida.
Estoy ahora probando con algo como:
cat fichOrig | awk '{print $2,ANYO,$5,$6,$7}' ANYO=`programa $3 $4`
pero también da error, dice que no encuentra un fichero o directorio:
awk: cannot open de (No such file or directory)
En este caso, "de" es parte del mensaje que devuelve mi "programa" cuando no se le llama con argumentos corrector, de donde deduzco que $3 y $4 no se están pasando correctamente en la llamada ANYO=`programa $3 $4`
Por otra parte, si introducimos valores válidos explícitamente:
cat fichOrig | awk '{print $2,ANYO,$5,$6,$7}' ANYO=`programa 1564 259200`
el programa funciona correctamente:
BLG_ 2009.994520548 5569885.5340 3105318.5555 -180595.2185
BLG_ 2009.994520548 5569885.5341 3105318.5373 -180595.2038
BLG_ 2009.994520548 5569885.5514 3105318.5618 -180595.1992
BLG_ 2009.994520548 5569885.5664 3105318.5608 -180595.2180
BLG_ 2009.994520548 5569885.5606 3105318.5601 -180595.2152
Entonces, ahora la pregunta sería: ¿como hago para que en la llamada
cat fichOrig | awk '{print $2,ANYO,$5,$6,$7}' ANYO=`programa $3 $4`
los argumentos $3 y $4 sean entendidos correctamente en ANYO=`programa $3 $4`?
Cat lo uso para leer el fichero original y pasarle los datos a awk.
Cuando digo llamar me refiero a ejecutar el programa que convierte semana y segundo en año.decimal, para insertarlo en la salida.
Estoy ahora probando con algo como:
cat fichOrig | awk '{print $2,ANYO,$5,$6,$7}' ANYO=`programa $3 $4`
pero también da error, dice que no encuentra un fichero o directorio:
awk: cannot open de (No such file or directory)
En este caso, "de" es parte del mensaje que devuelve mi "programa" cuando no se le llama con argumentos corrector, de donde deduzco que $3 y $4 no se están pasando correctamente en la llamada ANYO=`programa $3 $4`
Por otra parte, si introducimos valores válidos explícitamente:
cat fichOrig | awk '{print $2,ANYO,$5,$6,$7}' ANYO=`programa 1564 259200`
el programa funciona correctamente:
BLG_ 2009.994520548 5569885.5340 3105318.5555 -180595.2185
BLG_ 2009.994520548 5569885.5341 3105318.5373 -180595.2038
BLG_ 2009.994520548 5569885.5514 3105318.5618 -180595.1992
BLG_ 2009.994520548 5569885.5664 3105318.5608 -180595.2180
BLG_ 2009.994520548 5569885.5606 3105318.5601 -180595.2152
Entonces, ahora la pregunta sería: ¿como hago para que en la llamada
cat fichOrig | awk '{print $2,ANYO,$5,$6,$7}' ANYO=`programa $3 $4`
los argumentos $3 y $4 sean entendidos correctamente en ANYO=`programa $3 $4`?
No entiendo tu linea...
Cat fichOrig: salida del contenido del fichero fichOrig. Ok
awk '{print $2, ANYO... : que valor tiene ANYO en este momento? desde mi punto de vista ANYO no vale nada
ANYO=`programa $3 $4`: que valor tienen $3 y $4? no tengo la más remota idea.
Prueba de meterlo en un script bash y de ir viendo los valores que toman las variables, parece más un problema de lógica que otra cosa.
Cat lo uso para leer el fichero original y pasarle los datos a awk.
Cuando digo llamar me refiero a ejecutar el programa que convierte semana y segundo en año.decimal, para insertarlo en la salida.
Estoy ahora probando con algo como:
cat fichOrig | awk '{print $2,ANYO,$5,$6,$7}' ANYO=`programa $3 $4`
pero también da error, dice que no encuentra un fichero o directorio:
awk: cannot open de (No such file or directory)
En este caso, "de" es parte del mensaje que devuelve mi "programa" cuando no se le llama con argumentos corrector, de donde deduzco que $3 y $4 no se están pasando correctamente en la llamada ANYO=`programa $3 $4`
Por otra parte, si introducimos valores válidos explícitamente:
cat fichOrig | awk '{print $2,ANYO,$5,$6,$7}' ANYO=`programa 1564 259200`
el programa funciona correctamente:
BLG_ 2009.994520548 5569885.5340 3105318.5555 -180595.2185
BLG_ 2009.994520548 5569885.5341 3105318.5373 -180595.2038
BLG_ 2009.994520548 5569885.5514 3105318.5618 -180595.1992
BLG_ 2009.994520548 5569885.5664 3105318.5608 -180595.2180
BLG_ 2009.994520548 5569885.5606 3105318.5601 -180595.2152
Entonces, ahora la pregunta sería: ¿como hago para que en la llamada
cat fichOrig | awk '{print $2,ANYO,$5,$6,$7}' ANYO=`programa $3 $4`
los argumentos $3 y $4 sean entendidos correctamente en ANYO=`programa $3 $4`?
No entiendo tu linea...
Cat fichOrig: salida del contenido del fichero fichOrig. Ok
awk '{print $2, ANYO... : que valor tiene ANYO en este momento? desde mi punto de vista ANYO no vale nada
ANYO=`programa $3 $4`: que valor tienen $3 y $4? no tengo la más remota idea.
Prueba de meterlo en un script bash y de ir viendo los valores que toman las variables, parece más un problema de lógica que otra cosa.
Ahí está el problema, que antes de que awk imprima los resultados necesito trabajar con algunos de ellos (y para esto necesito llamar a un programa externo), las columnas $3 y $4, para generar un valor que será presentado en el resultado final. $3 y $4 son las columnas correspondientes de fichOrig
Hola,
Al final he solucionado el problema de dos formas: una cutre y otra que no está nada mal. Primero la cutre:
He conseguido realizar los cálculos externos con una llamada a system(), aunque he tenido que ayudarme de un fichero con funciones de awk y dos ficheros intermedios. En el fichero de órdenes de awk escribo:
function convierteFecha(sem,seg){
#creamos la orden de conversión
orden=sprintf("programa %s %s",sem,seg)
#ejecutamos la orden y capturamos la salida, que contiene retorno de carro
system(orden) | getline res
#devolvemos el resultado
return res
}
#imprimimos la línea con la fecha al final
{print $2,$5,$6,$7,convierteFecha($3,$4)}
Y en otro script escribo:
#!/bin/bashFICH=fichOrig
#creamos el fichero auxiliar
awk -f fichOrdenesAwk $FICH > aux
#quitamos las líneas en blanco
cat aux | awk '$0!~/^$/ {print $0}' > aux1
#reordenamos los elementos
cat aux1 | awk '{print $1,$5,$2,$3,$4}' > ${FICH}_bueno
#eliminamos los ficheros auxiliares
rm aux aux1
Llamando a este script leo con awk el contenido original, convierto la fecha, la pongo al final de la línea y guardo el resultado en un fichero auxiliar. Como la llamada a system() devuelve el resultado con retorno de carro y éste está al final de la línea, en el fichero auxiliar hay líneas en blanco, que quito también con awk y guardo en aux1. Por último, leo aux1 y ordeno las columnas como me interesa. Hasta aquí, la solución cutre.
La buena es tan fácil como:
FICH=fichOrigwhile read cod cod1 sem seg x y z aux; do
anyo=`programa $sem $seg`
echo $cod $anyo $x $y $z >> ${FICH}_bueno
done<$FICH
Vivir para ver, ni siquiera hace falta el awk. No sabía que se podía usar while read de esta forma.
mmmmhh...ya veo... ¿y no puedes hacer los cálculos sin llamar a un programa externo, directamente? manipula las variables desde bash
El problema es que lo del cambio de fecha no es trivial.