====== Examen Parcial - 75.08. Sistemas Operativos ====== **Cátedra:** Osvaldo Clua\\ **Fecha:** Segunda Oportunidad - Primer Cuatrimestre 2005\\ **Día:** 07/06/2005\\ **Tema:** PERL Esta página está incompleta; podés ayudar completando el material. ===== Enunciado ===== Desarrollar un comando PERL denominado "RankingCity.pl" que obtiene los totales de llamados (en minutos y en cantidad) que las ciudades hacen a un determinado destino. Para invocar este comando, el usuario deberá especificar: __Parámetro 1__: Nombre del archivo de ENTRADA __Parámetro 2__: Nombre de la Ciudad Destino. El archivo de ENTRADAA, esta desordenado, puede tener reistros repetidos, su separador de campos es el punto y coma y posee el siguiente formato: CodigoCiudadOrigen;CodigoCiudadDestino;cantidad_de_llamadas;cantidad_de_minutos Para obtener el Código de la ciudad destino contamos con un archivo de ciudades(denominado ciudades.txt) que esta ordenado por Código-de-Ciudad, no tiene registros repetidos, su separador de campos es el punto y coma y posee el siguiente formato: Codigo-de-Ciudad;Nombre de Ciudad **Es obligatorio el uso de una estructura de hash** para efectuar la suma de la cantidad de minuots y la suma de la cantidad de llamadas por ciudad origen. El campo ciudad origen es el que se debe emplear como clave. __Salida:__ se debe grabar en el archivo de salida lo siguiente: un primer registro de encabezamiento y luego las ciudades que llaman al destino especificado con su correspondiente cantidad total de minutos y cantidad total de llamadas. El separador de campos debe ser la coma. __Formato:__ * Para el registro de encabezamiento: "Proceso del día " , "Ciudad Destino solicitada", Nombre de la Ciudad Destino * Para cada ciudad que llama al destino: Código de Ciudad Origen, Cantidad total de minutos, cantidad total de llamadas. Solicitar al usuario, **leyendo del standard input** y durante el proceso, el nombre del archivo de salida. Si el archivo existe, NO PERDER LOS REGISTROS EXISTENTES, agregarle los nuevos registros. **No usar archivos auxiliares bajo ninguna hipótesis**. __Otras Validaciones:__ - Que sean exactamente 2 parámetros - Que el archivo de ENTRADA exista y tenga permisos de lectura - Que el archivo de ciudades.txt exista y tenga permisos de lectura - Que la ciudad destino exista en el archivo de ciudades En todos los casos si la validación da error mostrar por pantalla un mensaje descriptivo del error y terminar el proceso con algún código de error. ===== Ejemplo de corrida válida ===== __**Archivo de entrada con:**__\\ \begin{array}{|c|c|c|c|} \hline ROS001 & BA011 & 1234 & 2239.23 \\ \hline CBA3457 & BA011 & 345 &823.0 \\ \hline CBA3457 & ROS001 & 67 & 100.78 \\ \hline ROS001 & BA011 & 2000 & 3000\\ \hline BA011 & BA011 & 10 & 120.3345\\ \hline \end{array} __**Resultado:(si destino = Buenos Aires = BA011) Achivo de salida con:**__\\ \begin{array}{|c|c|c|} \hline \mbox{Proceso del dia 07-06-2005} & \mbox{Ciudad Destino Solicitada} & \mbox{Buenos Aires} \\ \hline ROS001 & 5239.23 & 3234 \\ \hline CBA3457 & 823.0 & 345 \\ \hline BA011 & 120.3345 & 10\\ \hline \end{array} ===== Resolución ===== #!/usr/bin/perl @args = @ARGV; if ($#args != 1) { die "ERROR: Cantidad de parametros incorrecta.\n"; } if (!(-e "ciudades.txt")) { // Si no existe... die "ERROR: El archivo ciudades.txt no existe.\n"; } if (!(-r "ciudades.txt")) { // Si no tiene permisos de lectura... die "ERROR: El archivo ciudades.txt no tiene permiso de lectura.\n"; } if (!(-e "$args[0]")) { die "ERROR: El archivo $args[0] no existe.\n"; } if (!(-r "$args[0]")) { die "ERROR: El archivo $args[0] no tiene permiso de lectura.\n"; } open CIUDADES, ")) && ($existe eq "no")) { chomp($linea); @reg_dest = split /;/, $linea; if ($reg_dest[1] eq $args[1]) { $existe = "si"; $cod_dest = $reg_dest[0]; $nom_dest = $args[1]; } } close CIUDADES; if ($existe eq "no") { die "ERROR: La ciudad de destino no existe en el archivo ciudades.txt\n"; } open IN, "<$args[0]"; while (defined($linea = )) { chomp($linea); @reg_ent = split /;/, $linea; if ("$reg_ent[1]" eq "$cod_dest") { if (exists $hash_llam{$reg_ent[0]}) { $hash_llam{$reg_ent[0]} = $hash_llam{$reg_ent[0]} + $reg_ent[2]; $hash_min{$reg_ent[0]} = $hash_min{$reg_ent[0]} + $reg_ent[3]; } else { $hash_llam{$reg_ent[0]} = $reg_ent[2]; $hash_min{$reg_ent[0]} = $reg_ent[3]; } } } close IN; print "Ingrese el nombre de archivo de salida: "; $salida = ; open OUT, ">>$salida"; @fecha = localtime(); $dia = $fecha[3]; $mes = $fecha[4]; $anio = 1900 + $fecha[5]; $fecha = join "-", "$dia", "$mes", "$anio"; $encabezado = join ",", "Proceso del dia $fecha", "Ciudad destino solicitada:", "$nom_dest"; print OUT "$encabezado\n"; while ( ($key, $value) = each %hash_llam) { $reg_salida = join ",", "$key", "$hash_min{$key}", "$value"; print OUT "$reg_salida\n"; } close OUT; ===== Otra Resolución ===== #!/usr/bin/perl # validación 1. ($#ARGV == 1) || die "Error, cantidad de parámetros incorrecta.\n"; $arch_in = $ARGV[0]; $destino = $ARGV[1]; $arch_ciudades = "ciudades.txt"; # validación 2. open(ENTRADA, "<$arch_in") || die "Error, no se pudo abrir el archivo de entrada: $arch_in.\n"; # validación 3. open(CIUDADES, "<$arch_ciudades") || die "Error, no se pudo abrir el archivo $arch_ciudades.\n"; # validación 4 $arch = join("", ); @lineas = split("\n", $arch); $codigo = ""; for $linea (@lineas) { #chop($linea); ($cod, $nom) = split(";", $linea); if ($nom eq $destino) { $codigo = $cod; } } close(CIUDADES); $codigo == "" || die "Error, no se encontro la ciudad en el archivo $arch_ciudades.\n"; print "Ingrese el nombre del archivo de salida: "; $archivo_salida = ; chop($archivo_salida); open(SALIDA, ">>$archivo_salida") || die "Error, no se pudo abrir en modo escritura el archivo $archivo_salida.\n"; # inicializo el hash. %cantidad = (); %minutos = (); # Levanto el archivo de entrada a memoria. $arch = join("", ); close(ENTRADA); # Lo separo en líneas. @lineas = split(/\n/, $arch); for $linea (@lineas){ @reg = split(/;/, $linea); ($cod_orig, $cod_dest, $cant, $min) = @reg; if ($cod_dest eq $codigo) { if (exists($cantidad{$cod_orig})){ $cantidad{$cod_orig} += $cant; $minutos{$cod_orig} += $min; } else { $cantidad{$cod_orig} = $cant; $minutos{$cod_orig} = $min; } } } # Ahora que ya tengo todos los datos que necesito: $fecha = `date`; chop($fecha); print SALIDA "Proceso del día $fecha, Ciudad Destino solicitada: $destino\n"; for $clave (keys(%cantidad)){ print SALIDA "$clave,$minutos{$clave},$cantidad{$clave}\n"; } close(SALIDA);