Examen Parcial - 75.08. Sistemas Operativos [Foros-FIUBA::Wiki]
 

Examen Parcial - 75.08. Sistemas Operativos

Cátedra: Osvaldo Clua
Fecha: Primer recuperatorio - Segundo Cuatrimestre 2002
Día: 12/11/2002
Tema: UNIX

Esta página está incompleta; podés ayudar completando el material.

Enunciado

Se tiene un directorio de Input con una serie de archivos a procesar. Programar un comando que grabe en un directorio de output un archivo con todos los registros de todos los archivos <cualquier nombre>.txt del directorio de Input, considerando que:

  1. Los registros deberán tener como segundo campo el nombre del archivo.
  2. El archivo de output debe ser llamado logresumen y debe ser grabado en el mismo directorio del cual se obtiene la información a procesar.
  3. El formato es igual para todos los archivos <cualquier nombre>.txt y la longitud del registro es variable. El separador de campo es ”:”.
  4. La cantidad de campos es igual en todos los archivos, pero se desconoce cual es esa cantidad.
  5. Se deberán procesar sólo los archivos que tienen mas de 8 campos. Los que no cumplan esta condición se debe grabar un archivo de error logerror.txt.

El comando debe comtemplar las siguientes opciones:

  1. -d <path> opción directorio de input, sin esta opción el directorio de input es el corriente.
  2. -a opción todos, con esta opción se tendrán que barrer todos los subdirectorios del directorio de input buscando archivos <cualquier nombre>.txt, en este caso el archivo de salida logresumen se graba en el directorio input “padre”. Para esta opción el campo que contiene el nombre del archvio tendrá que ser con el path completo.
  3. -e opción eliminar, se deberán eliminar todos los archivos que se procesan
  4. -f opción final, con esta opción se deberá grabar al final del archivo logresumen los siguientes mensajes:
    1. “Se procesaron n archivos” (donde n es la cantidad de archivos que se copiaron al logresumen).
    2. “Se rechazaron n archivos” (donde n es la cantidad de archivos que se rechazaron y no se copiaron al logresumen)
  5. Si el comando ejecuta con la opción -e, entonces agregar el mensaje: “Todos los archivos procesados fueron eliminados”

Resolución

#!/bin/bash
 
RecorrerDir() {
#$1 = Path que tengo que recorrer y en el que arranca posicionada la funcion
	for arch in *
	do
		if [ -d "$1/$arch" ]	# Si arch es un directorio, entra en él (esto incluye . y ..)
		then
			cd "$1/$arch"
			RecorrerDir "$PWD"	# Se llama a sí mismo (recursivamente
		else
			file=$(echo $arch | grep '.*\.txt$')	# Si es ".txt" asigno nombre a file
			if [ "${file:-1}" != '1' ]	# Me fijo si comando anterior asignó algo a file
			then
				ValidarArch "$file"	# Valida (<8 campos) y procesa
			fi
		fi
	done
}
 
ValidarArch() {	# Valida que el archivo tenga <8 campos y si el campo coincide con el filname (parametro) llama a AceptarReg
#$1 = Nombre del archivo (incluye ".txt")
IFS='
'	# Interanal File Separator ($* es su primer char). Separador de campos
local rechazar='0'	# Con local defino una variable invisible fuera del scop de la funcion scope. Rechaza o no el archivo
for reg in `cat $1`	# for variable in lista. cat va devolviendo línea a línea (registro). Recordar que $1 en esta funcion es $file (PRIMER parámetro de la recibido por la funcion, semejante a argv[1] con funcion main)
do
	if [ "$rechazar" = '0' ]	# Si no se rechaza (rechaza falso)...
	then
		declare -i cantcampos	# declaro variable entera cantcampos. ¿let cantcampos=0 no da igual?
		cantcampos=$(echo $reg | grep -o ';' | wc -l)	# cuenta campos: del reg, saca --only-matching con ';' y luego los cuenta ¿-l cuenta no líneas!?
		let cantcampos=$cantcampos+1	# cantcampos++
		if (($cantcampos > 8))
		then
			campo2=$(echo $reg | cut -d ';' -f 2)	# hermoso comando cut, saca el field 2, campos separados por ';'
			if [ "$campo2" = "$1" ]		# Compara 2do field con nombre de arch (param), pedido en ítem 1 enunciado
			then
				AceptarReg "$reg"	# campo2==coincide con el filename, acepta
			fi
		else
			rechazar='1'	# rechazo el registro
		fi
	fi
done
if [ "$rechazar" = '1' ]
then
	RechazarArch "$1"	# Si el archivo fue rechazado...
else
	let aceptados=$aceptados+1	# aceptados++
fi
if [ "$delete" = 'S' ]	# Si fue elgida la opción -w (era -e), borra el archivo
then
	rm $1
fi
}
 
AceptarReg() {
#$1 = Registro
echo $reg >> "$path/logresumen"	# Append del registro (con su \n al final)
}
 
RechazarArch() {
#$1 = Nombre del archivo
echo "Archivo $1 rechazado" >> "$path/logerror"
let rechazados=$rechazados+1
}
 
# COMIENZO DEL SCRIPT
 
path_anterior="$PWD"	# Guardo el directorio corriente
path="$PWD"		# Guardo el directorio corriente
while [ -n "$(echo $1 | grep '^-')" ]	# mientras los parámetros comiencen con "-"... (excepto path, por eso el shift)
do
	case $1 in 	# pruebo casos tomando "argv[1]". Notar que está definiendose un caso O EL OTRO (no varios al mismo tiempo).
		-d)	path="$2"	# si -d después viene el path, $2
			shift;;
		-a)	all='S';;	# si la opción fue elegida, defino variable (all, recorrer subdirs)
		-w)	delete='S';;	# No me pregunten por que, pero con -e no entra aca
		-f)	addtolog='S'	# si la opción fue elegida, defino variable ("final", agrego de msgs a logs)
			declare -i aceptados=0	# Uso declare pq son enteros
			declare -i rechazados=0;;
		* ) echo 'USO: parcial [-d <path>] [-a] [-w] [-f]'	# Si no se usan modificadores, mensaje y error (exit 1)
		    exit 1;;
	esac
	shift
done	# fin del while, ahora sé qué tengo que hacer según el caso (mediante variables definidas
 
cd "$path"	# Voy al path (en el que ya estoy.... cof cof
if [ "$all" = 'S' ]	# recordar que eq es para comparar strings (al reves de Perl)
then
	RecorrerDir "$path"	# Si ALL, recorro todos,
else				# else sólo el actual
	for arch in *	# for variable in lista.  (variable "arch"). Va poniendo en arch cada elemento de lista (en este caso c/n d arch)
	do
		file=$(echo $arch | grep '.*\.txt$')	# arch tiene el archivo actual del for, grep lo devuelve si termina en .txt
		if [ "${file:-1}" != '1' ]	# Si el grep seteo la variable file con algo... OBS: [ -z $file ] debería ser ==
		then
			ValidarArch "$file"	# me fijo si valida (si tiene 8 campos). Si es así, procesa
		fi
	done
fi
materias/75/08/parcial_20021112_1unix.txt · Última modificación: 2007/12/05 21:38 por rada
 
Excepto donde se indique lo contrario, el contenido de esta wiki se autoriza bajo la siguiente licencia: CC Attribution-Noncommercial-Share Alike 3.0 Unported


Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki