[Perl] pequeño script
Gunnar Wolf
gwolf@gwolf.cx
Mon, 7 Jul 2003 13:07:03 -0500
John Robeto dijo [Mon, Jul 07, 2003 at 12:02:52PM +0200]:
> Hola a todos.
> Intento hacer una chorrada de script pero no me sale.
> El script debe leer un archivo (txt) que contiene una
> lista de palabras y copiarlas a otro archivo sin que
> se repita ninguna, x ej.
>
> lista input: coche, casa, perro, perro, pájaro
> output: coche, casa, perro, pájaro
>
> lo he intentado convirtiendo el archivo de entrada en
> un @array y generando indices de array para la primera
> y segunda cadena, además de un contador $i, algo así:
Antes de ver tu código, te sugiero reescribirlo así:
----------------8<-----------------------
# Conviene manejar errores, no dejar todo al azar
open(ARCHIVO,'<file.txt') or die "No pude abrir file.txt: $!";
%palabras = (); # Creamos un nuevo hash vacío
# Procesamos cada línea del archivo
while (my $linea = <ARCHIVO>) {
# Según tu ejemplo, cada línea contiene varias palabras
# separadas por comas
foreach my $palabra (split(', ', $linea)) {
# Acá tomamos cada palabra por separado y le creamos una entrada
# en %palabras
$palabras{$palabra} = 1;
}
}
# Ya no necesitamos tener a ARCHIVO abierto - Y sólo a partir de aquí
# necesitamos a SALIDA
close(ARCHIVO);
open(SALIDA,'>fileSal.txt') or die "No pude abrir fileSal.txt: $!";
# ¿No te parece más simple? ¡Con un sólo enunciado cras la lista
# completa y ordenadita!
print SALIDA join("\n", sort keys %palabras);
close(SALIDA);
----------------8<-----------------------
> open (ARCHIVO, "< file.txt");
> open (SALIDA, "> fileSal.txt");
>
> @lista = <ARCHIVO>;
>
> $i = 0; ### contador en cero
> $pal1 = $lista[$0]; ### 1ra palabra de @lista
> $pal2 = $lista[$i]; ### 2da palabra de @lista
>
>
> foreach $pal (@lista){
> if ($pal1 ne $pal2){ ##sin son iguales $i++
> $i++;}
> print SALIDA "$pal2 \n";
> }
>
> Gracias a quien pueda decirme en qué fallo.
Ahora, yendo a encontrar la falla en tu programa: Se ve que vienes de C
;-) ¿Para qué quieres el contador $i? ¿Qué utilidad te da? Si quieres el
total de palabras, mejor (en mi versión) pide 'scalar keys %palabras' -
'keys %palabras' te da un arreglo con las llaves del hash, y obligarlo a
ser evaluado como 'scalar' te da la cantidad de elementos que tiene.
Acerca de tu programa:
- ¿Qué tienes en $0? ¿Por qué lo usas como subíndice de $lista?
- Al asignar $lista[$i] a $pal, $i fue ya evaluado - En tu ciclo vas
incrementando $i, pero $pal2 ya fue asignado, y $i se vuelve un simple
contador de vueltas.
- Con la lógica que estás manejando (aún si funcionara ;-) ), sólo
eliminarías palabras repetidas adyacentes, no si están separadas. En
todo caso tendrías que hacer dos arreglos e iterar sobre todos los
elementos de ambos buscando repeticiones.
Saludos,
--
Gunnar Wolf - gwolf@gwolf.cx - (+52-55)5630-9700 ext. 1366
PGP key 1024D/8BB527AF 2001-10-23
Fingerprint: 0C79 D2D1 2C4E 9CE4 5973 F800 D80E F35A 8BB5 27AF