Cátedra: Clúa
Fecha: 1er Oportunidad - 1er Cuatrimestre 2009
Día: 26/06/2009
Tema: Perl (Tema 1)
Leer un archivo de input cuyo nombre es pasado como parámetro y cuyo separador es pasado como parámetro (parámetros uno y dos respectivamente).
Sumar las cantidades por producto usando una estructura hash (el campo producto es el que se emplea como clave y el campo cantidad es el que se debe acumular).
Grabar un archivo de salida denominado <“nombre”>.sal (este <“nombre”> debe ser solicitado por standard input) los productos con cantidad acumulada superior a 1000.
Como el formato del archivo de entrada es desconocido, además se deben pasar como parámetros la ubicación del campo producto y la ubicación del campo cantidad.
Ejemplo: para el archivo datos.prd, con separador coma y formato: fecha factura cliente cantidad producto precio, la invocación correcta es: datos.prd , 5 4
Condiciones para la resolución:
1 Que el archivo de entrada exista, se pueda leer, tenga al menos 2 campos y no este vacio.
2 Que los parámetros de ubicación deteminen ubicaciones válidas y distintas [Ejemplo de invocaciones erróneas: datos.prd , 4 4 (porque son iguales) o datos.prd , 7 4 (porque el archivo de input tiene solo 6 campos)]
3 Que sean 4 parámetros, si se pasan más ignorar los que sobran, si se pasan menos es error.
Parámetro 1: Nombre del archivo de Input
Parámetro 2: Separador del archivo de Input
Parámetro 3: Ubicación del campo producto
Parámetro 4: Ubicación del campo cantidad
4 Si se verifica alguno de estos errores mostrar por pantalla un mensaje descriptivo del error y cancelar el programa.
5 No usar archivos auxiliares, comandos Unix (bajo ningún concepto) ni expresiones regulares (excepto las expresiones regulares simples de las funciones predefinidas de perl).
6 Abrir y cerrar adecuadamente los archivos. En todos los archivos (input y output) el separador de registros es el new line.
#!/usr/bin/perl -w ################################################################ # AUTOR: Maximiliano Milicich (maximiliano.milicich@gmail.com) ################################################################ if ($#ARGV < 3) { print "Sintaxis incorrecta: debe informar al menos 4 parametros.".$/; exit 1; } $nombrearch_input = $ARGV[0]; $separador = $ARGV[1]; $poscampo_prod = $ARGV[2]; $poscampo_cant = $ARGV[3]; # Validacion de los parms de entrada: if ($poscampo_prod == $poscampo_cant || $poscampo_prod <= 0 || $poscampo_cant <= 0) { print "Error: Posicion de campo cantidad y producto deben ser mayores a cero y no pueden ser iguales".$/; exit 1; } open(ARCH_IN, '<'.$nombrearch_input) || die "No se pudo abrir el archivo $nombrearch_input"; close(ARCH_IN); if ($separador =~ /^\s*$/) { print "Separador no puede ser vacio".$/; exit 1; } # Definimos la minima cant de campos q va a necesitar cada registro, en base a los parms de entrada: if ($poscampo_prod > $poscampo_cant) { $min_cantcampos = $poscampo_prod; } else { $min_cantcampos = $poscampo_cant; } # Pedimos al usuario nombre de archivo de salida: $nombrearch_output = ''; while ($nombrearch_output =~ /^\s*$/) { print "Ingrese el nombre del archivo de salida: "; $nombrearch_output = <STDIN>; } chomp($nombrearch_output); $nombrearch_output = $nombrearch_output.'.sal'; # Procesamos la data del archivo: open(ARCH_IN, '<'.$nombrearch_input) || die "No se pudo abrir el archivo $nombrearch_input"; %totalcantxprod = (); while ($linea = <ARCH_IN>) { if ($linea =~ /^\s*$/) { next; } @campos = split(/$separador/, $linea); $cantcampos = $#campos + 1; if ($cantcampos < $min_cantcampos) { print "Error: Los registros del archivo $nombrearch_input deben tener al menos $min_cantcampos campos".$/; close(ARCH_IN); exit 1; } $totalcantxprod{$campos[$poscampo_prod -1]} += $campos[$poscampo_cant -1]; } close(ARCH_IN); # Armamos la Salida: open(ARCH_OUT, ">$nombrearch_output") || die "No se pudo abrir archivo output $nombrearch_output"; foreach $prod (keys(%totalcantxprod)) { # Otra opcion para esto (mas cortita) es : while (($prod, $cant) = each %totalcantxprod) { ... } $cant = $totalcantxprod{$prod}; if ($cant > 1000) { print ARCH_OUT $prod.$/; } } close(ARCH_OUT); # Llamadas a Sistema Operativo! # Con esto vemos el resultado y borramos el archivo, asi podemos volver a testear la corrida :-) system("cat $nombrearch_output"); system("rm $nombrearch_output");
$ script.pl datos.ent , 2 3
Archivo datos.ent
lala,ZANAHORIA,100,lala lala,ZANAHORIA,100,lala lala,PEPINO,100,lala lala,KANIKAMA,500,lala lala,ZANAHORIA,100,lala lala,PEPINO,100,lala lala,TOFU,100,lala lala,ZANAHORIA,100,lala lala,KANIKAMA,500,lala lala,ZANAHORIA,100,lala lala,PEPINO,100,lala lala,ZANAHORIA,100,lala lala,PEPINO,100,lala lala,KANIKAMA,500,lala lala,PEPINO,800,lala
Resultado: