
Tengo un archivo de datos abc.txt en el siguiente formato:
BALT 1
54.500 -161.070
3.95863757
0.01691576
BARM 2
-9.200 67.120
4.07529868
0.01951653
BKSR 3
43.830 142.520
4.08919819
0.00587340
Necesito convertirlo al formato:
BALT 1
54.5000000 -161.070000
0.3958637E+01
0.1691576E-01
BARM 2
-9.20000000 67.1200000
0.4075298E+01
0.1951653E-01
BKSR 3
43.8300000 142.520000
0.4089198E+01
0.5873400E-02
El total de espacios ocupados por los números en la segunda línea debe ser 10 excluyendo el signo -ve (por ejemplo, 54,500 como 54,5000000 y -161,070 como -161,070000). Los espacios para la tercera y cuarta línea deben ser 13 (por ejemplo, 3,95863757 como 0,3958637E+01). Y BALT o BARM son variables, pueden ser otras palabras de cuatro caracteres.
Gracias.
Respuesta1
versión 3use un archivo awk como
function tenth(x) {
u = x ; if ( u < 0 ) u = -x ;
b=10 ;
a=b-2 ;
if ( u >= 10 ) {
d=int(log(u)/log(10)) ;
a=b-d-1 ;
}
printf "%*.*f",b,a,x ;
}
length($1) == 4 { print ; next ;}
NF == 1 { d=int(log($1)/log(10)) ;if (d> -1) d++ ; printf " %.7fE%+03d\n",$1/(10^d),d ;}
NF == 2 { printf " " ; tenth($1); printf " " ; tenth($2) ; printf "\n" ;}
dónde
lengtht$1) == 4 { print ; next ;}
dejará en paz la línea donde el primer campo tiene cuatro letras (aunque puede ser 1234)function tenth(x)
: define una función que ajusta el formato."%*.*f"
cadena de ajuste de tamaño/precisión de%f
conversión. el primero * se reemplaza por b, el segundo * se reemplaza por a.int(log()/log(10))
¿Proporciona un registro decimal que ajuste la representación a su necesidad específica?
úsalo con
awk -f f.awk input
que dan como resultado
BALT 1
54.5000000 -161.070000
0.3958638E+01
0.1691576E-01
BALT 2
-9.20000000 67.1200000
0.4075299E+01
0.1951653E-01
BALT 3
43.8300000 142.520000
0.4089198E+01
0.5873400E-02
0.00000000 1.00000000
-3.14150000 2.71828183
Respuesta2
Quizás algo como:
awk '
!/[[:alpha:]]/{
if (NF == 1)
$0 = sprintf(" %.7E", $0 * 10)
else
$0 = sprintf(" %.8f %.8f", $1, $2)
}
{print}' | sed '
s/\([0-9.]\{10\}\)[0-9]*/\1/g
s/\([1-9]\)\.\(.*\).E/0.\1\2E/'
Respuesta3
Puedes conseguirlo sin awk con:
while read line; do echo $line; read a; read b; read c; printf "%.7f %.7f\n %.7e\n %.7e\n" $a $b $c; done < data.txt
Sin embargo, usar printf de esta manera puede generar algunos problemas si utiliza alguna configuración regional con coma en lugar de punto. En este caso deberías poder solucionarlo con:
while read line; do echo $line; read a; read b; read c; LC_NUMERIC="en_US.UTF-8" printf "%.7f %.7f\n %.7e\n %.7e\n" $a $b $c; done < data.txt
Por supuesto, en un script deberías formatearlo mejor con retorno de carro y sangría.