Difference between revisions of "ProvaPratica 2013.07.18"
		
		
		
		
		
		Jump to navigation
		Jump to search
		
				
		
		
	
| Line 279: | Line 279: | ||
| 				if( s.st_mode & S_IFDIR ) //è un dir | 				if( s.st_mode & S_IFDIR ) //è un dir | ||
| 				{   | 				{   | ||
| − | 					if ( strcmp( namelist[n]->d_name , ".." ) == 0 ) | + | 					if ( strcmp( namelist[n]->d_name , ".." ) == 0 )//si deve escludere ".." | 
| 					{   | 					{   | ||
| 						continue;   | 						continue;   | ||
| 					}   | 					}   | ||
| − | 					if( strcmp( namelist[n]->d_name , "." ) == 0 ) | + | 					if( strcmp( namelist[n]->d_name , "." ) == 0 )//si deve escludere "." | 
| 					{   | 					{   | ||
| 						continue;   | 						continue;   | ||
| Line 296: | Line 296: | ||
| 					if( s.st_mode & S_IFREG ) //è un file | 					if( s.st_mode & S_IFREG ) //è un file | ||
| 					{   | 					{   | ||
| − | 						datest=symlink(pathwithname,pathwithname2); | + | 						datest=symlink(pathwithname,pathwithname2);//torna 0 al successo -1 altrimenti | 
| − | 						if(datest==-1) //link esiste | + | 						if(datest==-1) //se simlink fallisce => link esiste | 
| 						{ | 						{ | ||
| 							i=1; | 							i=1; | ||
| − | 							while(datest!=0) | + | 							while(datest!=0)//finchè simlink non ha successo | 
| 							{ | 							{ | ||
| 								istr=(char *)malloc(32); | 								istr=(char *)malloc(32); | ||
Revision as of 10:02, 30 November 2013
[Python 3]
'''
Prova Pratica di Laboratorio di Sistemi Operativi
18 luglio 2013
Esercizio 3
URL: http://www.cs.unibo.it/~renzo/so/pratiche/2013.07.18.pdf
@author: Tommaso Ognibene
'''
import os, sys
def Main(argv):
    # Check number of arguments
    if len(argv) != 3:
        print("The function requires two arguments to be passed in.")
        return
    
    # Check parameters
    srcDir = str(argv[1])
    dstDir = str(argv[2])
    if not os.path.isdir(srcDir):
        print("First argument should be an existing directory.")
        return
    if not os.path.isdir(dstDir):
        print("Second argument should be an existing directory.")
        return
    
    # Build a dictionary with key-value pair {file base name - occurrences}
    nameFreq = { }
    for dirPath, dirNames, fileNames in os.walk(srcDir):
        for fileName in fileNames:
            fileBaseName, _ = os.path.splitext(fileName)
            nameFreq[fileBaseName] = nameFreq.get(fileBaseName, -1) + 1
            
            # Create a soft link
            freq = nameFreq[fileBaseName]
            linkName = "{0}{1}".format(fileBaseName, str(freq) if freq > 0 else "")
            srcPath = os.path.join(os.path.abspath(dirPath), fileName)
            dstPath = os.path.join(dstDir, linkName)
            if not os.path.lexists(dstPath):
                os.symlink(srcPath, dstPath)
        
    print("Done!")
if __name__ == "__main__":
    sys.exit(Main(sys.argv))
Questa è la mia versione
import os, sys
def collectfiles(arg1,arg2): 
	fcd = os.listdir('{0}'.format(arg1))
	while fcd != []:
		B=str(fcd.pop())
		C='{0}/{1}'.format(arg1,B)
		if os.path.isdir('{0}'.format(C)):
			collectfiles(C,arg2)
		elif os.path.isfile('{0}'.format(C)):
			try:
				os.symlink('{0}'.format(C), '{0}/{1}'.format(arg2,B))
			except OSError:
				i=1
				while True:
					try:
						os.symlink('{0}'.format(C), '{0}/{1}{2}'.format(arg2,B,i))
						break
					except OSError:
						i=i+1
try:
	collectfiles(str(sys.argv[1]),str(sys.argv[2]))
except OSError:
		print("Invalid Directory!")
-Fede
Leggendo la tua versione ho pensato che in effetti se i file sono """pochi""" l'hash-table non e' necessaria. E' sufficiente un controllo iterativo.
'''
Prova Pratica di Laboratorio di Sistemi Operativi
18 luglio 2013
Esercizio 3
URL: http://www.cs.unibo.it/~renzo/so/pratiche/2013.07.18.pdf
@author: Tommaso Ognibene
'''
import os, sys
def Main(argv):
    # Check number of arguments
    if len(argv) != 3:
        print("The function requires two arguments to be passed in.")
        return
    
    # Check parameters
    srcDir = str(argv[1])
    dstDir = str(argv[2])
    if not os.path.isdir(srcDir):
        print("First argument should be an existing directory.")
        return
    if not os.path.isdir(dstDir):
        print("Second argument should be an existing directory.")
        return
    
    # Traverse the directory tree and create a soft link for each file
    for dirPath, _, fileNames in os.walk(srcDir):
        for fileName in fileNames:
            # 'example.pdf' -> 'example'
            # 'example.xml' -> 'example'
            fileBaseName, _ = os.path.splitext(fileName)
            linkName = fileBaseName
            srcPath = os.path.join(os.path.abspath(dirPath), fileName)
            dstPath = os.path.join(dstDir, linkName)
            i = 0
            while os.path.isfile(dstPath):
                # 'example' will point to 'example.pdf'
                # 'example1' will point to 'example.xml'
                i += 1
                linkName = fileBaseName + str(i)
                dstPath = os.path.join(dstDir, linkName)
            if not os.path.lexists(dstPath):
                os.symlink(srcPath, dstPath)
        
    print("Done!")
if __name__ == "__main__":
    sys.exit(Main(sys.argv))
Ecco la mia versione in bash
#! /bin/bash
 
BornAgainFede () {
for f in "$1"/*; do
	bn=$(basename "$f")
	if [[ -f $f ]] ; then
		if [[ -h "$2"/"$bn" ]] ; then
			i=1
			while [[ -h "$2"/"$bn$i" ]] ; do
			let "i += 1" 
			done
			ln -s "$1"/"$bn" "$2"/"$bn$i"
		else
			ln -s "$1"/"$bn" "$2"/"$bn"
		fi
	fi
	if [[ -d $f ]] ; then
		BornAgainFede "$1"/"$bn" "$2"
	fi
done
}
 
BornAgainFede "$1" "$2"
-Fede
Versione by Daniele Cortesi:
from sys import argv
import os
#controllo se il programma e' stato chiamato correttamente
if len(argv)<3:
	print "uso: programma cartella1 cartella2"
	exit(1)
	
dir1=argv[1]
dir2=argv[2]
#controllo che gli argomenti siano effettivamente cartelle
if not os.path.isdir(dir1) or  not os.path.isdir(dir2):
	print "cartelle non valide"
	exit(1)
cartelle=[os.getcwd()+"/"+dir1] #lista che conterra' mano a mano tutte le sottocartelle
files={} #dizionario con nomefile: [lista con tutti i file che si chiamano "nomefile"]
while len(cartelle)>0:
	c=cartelle.pop() 
	for f in os.listdir(c): #analizzo tutti i file nella cartella c
		#se f non e' una cartella, allora lo inserisco nel dizionario se non c'e', altrimenti aggiungo il suo percorso alla lista
		if not os.path.isdir(c+"/"+f):
			if not files.has_key(f):
				files[f]=[c+"/"+f]
			else: files[f].append(c+"/"+f)
		#se f invece e' una cartella, la aggiungo alla lista cosi' alla prossima iterazione (o dopo in caso di piu' cartelle) verra' analizzata
		else: cartelle.append(c+"/"+f)
		
#creo i link simbolici	
for k in files.keys():
	for i,f in enumerate(files[k]):
		link=k
		if (i>0): link+=str(i)
		os.symlink(f, dir2+"/"+link)
exit(0)
Osservazioni
Per prima cosa, bel lavoro!
Di seguito riporto alcune osservazioni che mi sono venute in mente, prendetele assolutamente con soli fini "costruttivi"! 
- Se non sbaglio, i due programmi (quello di Tommaso e quello di Fede) hanno un comportamento diverso per quanto concerne l'interpretazione del nome file e, in particolare, dell'estensione:
- Per Tommaso:
- dir1/example.pdf --> example
- dir1/example.txt --> example1
- dir1/dirX/example.pdf --> example2
 
- Per Fede:
- dir1/example.pdf --> example.pdf
- dir1/example.txt --> example.txt
- dir1/dirX/example.pdf --> example.pdf1
 
- interpretando in modo "stringente" del testo dell'esercizio avrei ipotizzato un comportamento come quello di Fede.
 
- Per Tommaso:
- Nel codice sorgente c'è in generale poco "commento". Commentare il codice è essenziale: permette ad altri di capire immediatamente le scelte implementative fatte e permette a voi di capire al volo il perché di queste scelte nel caso dobbiate riprendere in mano il vostro codice dopo un po' di tempo. Quindi: commentate!!!
- Bash si presta molto all'esercizio
/*
ESERCIZIO 3.
*/
#include<unistd.h>  
#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
#include<dirent.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
void collectandlink(char *arg1, char *carg2)
{ 
	struct dirent **namelist; 
	int n; 
	n = scandir( arg1 , &namelist, 0, alphasort); 
	if (n < 0) 
		perror("scandir"); 
	else 
	{ 
		while(n--)
		{ 
			int i;
			char* istr;
			int datest;
			char *pathnametmp;
			char *pathwithname=(char *)malloc(512);
			char *pathwithname2=(char *)malloc(512);
			strcpy(pathwithname,arg1);
			strcpy(pathwithname2,carg2);
			strcat(pathwithname,"/");
			strcat(pathwithname2,"/");
			strcat(pathwithname,namelist[n]->d_name);
			strcat(pathwithname2,namelist[n]->d_name);
			struct stat s; 
			if( stat(pathwithname,&s) == 0 ) 
			{  
				if( s.st_mode & S_IFDIR ) //è un dir
				{ 
					if ( strcmp( namelist[n]->d_name , ".." ) == 0 )//si deve escludere ".."
					{ 
						continue; 
					} 
					if( strcmp( namelist[n]->d_name , "." ) == 0 )//si deve escludere "."
					{ 
						continue; 
					}  
					else 
					{
						collectandlink(pathwithname,carg2);
					}
				} 
				else 
				{
					if( s.st_mode & S_IFREG ) //è un file
					{ 
						datest=symlink(pathwithname,pathwithname2);//torna 0 al successo -1 altrimenti
						if(datest==-1) //se simlink fallisce => link esiste
						{
							i=1;
							while(datest!=0)//finchè simlink non ha successo
							{
								istr=(char *)malloc(32);
								pathnametmp=(char *)malloc(544);
								strcpy(pathnametmp,pathwithname2);
								sprintf(istr, "%d", i);
								strcat(pathnametmp,istr);
								datest=symlink(pathwithname,pathnametmp);
								free(istr);
								free(pathnametmp);
								i=i+1;
							}
						}
					} 
				} 
			}
			free(pathwithname);
			free(pathwithname2);
		} 
	}
}
int main(int argc, char *argv[]){ 
collectandlink(argv[1],argv[2]); 
return 1; 
}
-Da fede&pirata