Hola a todos.
Lo primero el problema:
tengo un fichero de texto, supongamos algo como:
a1 a2 a3 a4 a5
b1 b2 b3 b4 b5
c1 c2 c3 c4 c5
d1 d2 d3 d4 d5
e1 e2 e3 e4 e5
y quiero convertirlo en su "transpuesto";
a1 b1 c1 d1 e1
a2 b2 c2 d2 e2
a3 b3 c3 d3 e3
a4 b4 c4 d4 e4
a5 b5 c5 d5 e5
...y la pregunta del millón. ¿hay algún comando que lo haga
directamente?
Estoy programando un script en perl, pero me está quedando de un
guarro que asusta.
Un saludo a todos.
- --
Han Solo
The Rebel Alliance
Emacs is not on every system
So what? [...] Do you tell your administrative people to stick with
notepad.exe? Do you tell your fat kids they can only have the crummy
games that come with their video games or plain dress that comes with
Barbie?
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: Processed by Mailcrypt 3.5.6 <http://mailcrypt.sourceforge.net/>
iD8DBQE+Q9Q/4FjpJaPEp20RAuuyAJ9FGWngiNZ7/qAlq1MsEkqrLJXuXgCfTsw8
51hTssae99d+ldMg0VLaZ1Q=
=iOFH
-----END PGP SIGNATURE-----
¿En 30 líneas te vale?
Estaba aburrido y me he puesto a hacerlo. No queda tan guarro con un par
de trucos:
------------------------------
#!/usr/bin/perl -w
$separador = " ";
while (<>) # Para cada línea:
{
chop;
@mat = split /$separador/,$_; # Dividimos la línea
for ($i=0; $i<@mat; $i++) # Para cada elemento:
{ # La matriz n es un índice que
# cuenta los elentos que hay en cada
# dimensión de mattr.
defined $n[$i] or $n[$i] = 0; # Cuenta que iniciamos en 0.
$mattr[$i][$n[$i]] = $mat[$i]; # Llenamos la matriz principal por
# columnas. mattr tiene 2 dimensiones.
$n[$i]++;
}
}
foreach (@mattr) # Ahora la escribirmos por filas
{
@tmp = @{$_}; # Los elementos de la 2ª dimensión son
# referencias a matriz (punteros).
foreach (@tmp)
{
print $_.$separador;
}
print "\n";
}
-----------------------
El asunto es llenar la matriz en columnas y escribirla por filas. Para eso
se usa la matriz $mattr ($mat transpuesta). Como cada elemento es una
referencia se desreferencia. Los dos foreach anidados son para dar
formato. Se habría conseguido lo mismo fijando $" = $separador y omitiendo
el foreach interior. Pero eso es ya lo de menos. Se puede hacer más
compacto, pero se entiende peor.
Échale un ojo y asegúrate de que lo entiendes antes de usarlo, que no está
bien dar las cosas ya hechas.
Por cierto, hay que llamarlo: trans fichero o bien trans < fichero.
Saludos.
--
·········································································
·· Reinoso G. EA4BAO r einoso.bao@wanadoo.e s ··
·· http://perso.wanadoo.es/reinoso.bao ··
·········································································
"Reinoso G." <rei...@probando.com> writes:
[magnífico script para transponer un fichero]
Es exactamente lo que necesitaba, muchas gracias.
Yo lo estaba haciendo sin meterlo todo en una matriz, según lo iba
leyendo de la entrada estándar, pero se forma un galimatías del carajo
de ficheros temporales.
Un saludo.
- --
Un Saludo
Han Solo
The Rebel Alliance
Emacs is not on every system
So what? [...] Do you tell your administrative people to stick with
notepad.exe? Do you tell your fat kids they can only have the crummy
games that come with their video games or plain dress that comes with
Barbie?
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: Processed by Mailcrypt 3.5.6 <http://mailcrypt.sourceforge.net/>
iD8DBQE+Q+9J4FjpJaPEp20RAi5IAJ9UYYRIeB/92Q+pbCi4NFrGr7bljACguMu+
UZ+dhOZle615KgzEjYh8QMQ=
=1Z1e
-----END PGP SIGNATURE-----
#! /usr/bin/awk -f
{
split($0, a);
for (i = 1; i <= NF; i++) {
b[i] = b[i] " " a[i];
}
}
END {
for (i = 1; i <= NF; i++) {
print b[i]
}
}
No es mío, ayer lo posteó alguien en comp.unix.shell. Hace exactamente
lo que pides.
Un saludo.
--
Grupo de usuarios de Mandrake: | i386-slackware-linux-gnu (2.4.20)
<http://www.mandrakeusers.org> | bash: 2.05a.0(1)-release
aru | <cata...@nospammail.net>
: tengo un fichero de texto, supongamos algo como:
: a1 a2 a3 a4 a5
: b1 b2 b3 b4 b5
: c1 c2 c3 c4 c5
: d1 d2 d3 d4 d5
: e1 e2 e3 e4 e5
: y quiero convertirlo en su "transpuesto";
: a1 b1 c1 d1 e1
: a2 b2 c2 d2 e2
: a3 b3 c3 d3 e3
: a4 b4 c4 d4 e4
: a5 b5 c5 d5 e5
- Opcion A:
Supongamos que tienes tu matriz de 3x3 en "file":
tr ' ' \\012 < file | ./catsplit.sh 3 file.out | ed
te dejara en file.out la matriz deseada.
- catsplit.sh -------------------------------------------------------------
#!/bin/sh
#
# use:
# $0 numlines fileout < file | ed
#
rm -f $2
line=0
first_time=true
echo H
echo a
while read s
do
if [ $line -eq $1 ]
then
if $first_time
then
echo .
echo 1
first_time=false
else
echo 1
fi
line=0
fi
if $first_time
then
echo $s
else
echo 's/$/ '"$s"'/'
echo '+'
fi
line=`expr $line + 1`
done
echo w $2
echo q
---------------------------------------------------------------------------
- Opcion B:
(
cut -d" " -f1 file | tr \\012 " "; echo
cut -d" " -f2 file | tr \\012 " "; echo
cut -d" " -f3 file | tr \\012 " "; echo
) | sed 's/ $//'
- Otras mas eficientes:
usar algun lenguaje que soporte matrices.
--
PGP and other useless info at \
http://www.cps.unizar.es/~spd/ \
finger://daphne.cps.unizar.es/spd \ Timeo Danaos et dona ferentes
ftp://ivo.cps.unizar.es/pub/ \ (Virgilio)
Han Solo wrote:
> tengo un fichero de texto, supongamos algo como:
>
> a1 a2 a3 a4 a5
> b1 b2 b3 b4 b5
> c1 c2 c3 c4 c5
> d1 d2 d3 d4 d5
> e1 e2 e3 e4 e5
>
> y quiero convertirlo en su "transpuesto";
>
> a1 b1 c1 d1 e1
> a2 b2 c2 d2 e2
> a3 b3 c3 d3 e3
> a4 b4 c4 d4 e4
> a5 b5 c5 d5 e5
[...]
> Estoy programando un script en perl, pero me está quedando de un
> guarro que asusta.
Bueno, en Perl ni idea, pero si quieres darle una oportunidad a Python, en 7
líneas lo tienes listo:
Supongamos que tienes el fichero foriginal.txt y quieres obtener ftrans.txt
$ python transpo.py foriginal.txt > ftrans.txt
transpo.py-----------------------------
import sys
f=open(sys.argv[1])
L=f.readlines()
f.close()
L2=[l.split() for l in L]
L3=zip(*L2)
for l in L3: print " ".join(l)
- ----------------------------------------
Con la versión estable actual (2.2.2) funciona perfectamente ;-)
Salut!
- --
Sergi Faber
Linux User #157835
GnuPG Pub Key 0x91DC7713 a pgp.escomposlinux.org
Slackware 8.1 -> n'hi ha d'altres?
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)
iD8DBQE+SY2sTcpsM5HcdxMRAsKaAJ4xOyRdC46Rk07T2DhOZSM2xnFBaACfVGLK
ZSyXX0g6VwSbHysFQ3mGBRk=
=9lD1
-----END PGP SIGNATURE-----