Page 1 sur 1

Resolu : Renommer fichiers

Posté : 05 oct. 2011, 10:39
par baddev
Bonjour

Je cherche a renommer les fichiers d'un repertoire donne, apres avoir eliminer certains caracteres speciaux, mais le script suivant bloque et je ne vois pas ou. Un peu d'aide serait la bienvenue :

Code : Tout sélectionner

<?php $tab_file = array(); function filter($in) { $search = array ('@[éèêëÊË]@i','@[àâäÂÄ]@i','@[îïÎÏ]@i','@[ûùüÛÜ]@i','@[ôöÔÖ]@i','@[ç]@i','@[ ]@i','@[^a-zA-Z0-9_]@'); $replace = array ('e','a','i','u','o','c','_',''); return preg_replace($search, $replace, $in); } $dirname = '/home/dev/smilies'; $dir = opendir($dirname); while($file = readdir($dir)) { if($file != '.' && $file != '..' && !is_dir($dirname.$file)) { $tab_tmp = explode(".", $file); $tab_file[$tab_tmp[0]] = $tab_tmp[1]; foreach($tab_file as $cle=>$valeur) { $rename_phrase = "rename(" . $dirname . "/" . $file .", " . $dirname . "/" . strtolower(filter($cle)) . "." . $valeur . ")\n"; rename($dirname . "/" . $file, $dirname . "/" . strtolower(filter($cle)) . "." . $valeur); } } } closedir($dir); ?>
La ou la "rename_phrase" m'affiche exactement ce que je veux faire, avec une bonne syntaxe, quand la fonction rename s'execute : elle fait n'importe quoi.. les noms de fichiers ne correspondent plus et elle ne parvient pas a trouver les fichier (no such file or directory :? ??? )

Merci

Re: Renommer fichiers

Posté : 05 oct. 2011, 11:36
par moogli
salut,

le ofreach n'a pas lieu d'être ici tu ne peux travailler sur un tableau, d'ailleur ton code n'est bon que pour des fichiers avec fichier.ext s'il contient un point c'est mort !

il faut prendre ce qu'il y a après le dernier point pour l'extension et tous ce qu'il y a avant pour le nom du fichier.

travail juste avec le while !

Perso j'ai fait ça pour php5 (à partir de la doc et ses commentaires), ça modifie l'extension mais bon c'est pas compliquer d'appliquer un changement sur le nom plutôt que l'extension ;)
<?php
$extensionfinal = '.php5';
$extensionoriginal = '.php';
$ite=new RecursiveDirectoryIterator('./');
$bytestotal=0;
$nbfiles=0;
echo '<pre>';
foreach (new RecursiveIteratorIterator($ite) as $filename=>$cur) {
    $filesize=$cur->getSize();
    $bytestotal+=$filesize;
    $nbfiles++;
	$sansextension = substr($filename,0, strrpos($filename,'.'));
	$extension = strrchr($filename,'.');
	if ($extension == $extensionoriginal){
		rename($filename,$sansextension.$extensionfinal);
		echo '<span>le fichier ', $filename ,' a été renommé en : ',$sansextension.$extensionfinal.'</span><br />';
	}
}
echo '</pre>';
$bytestotal=number_format($bytestotal);
echo "Total: $nbfiles files, $bytestotal bytes <br />";
?>
parcourt récursif des répertoires poru modifier l'extention des fichier des $extensionoriginal à $extensionfinal :)

@+

Re: Renommer fichiers

Posté : 05 oct. 2011, 11:43
par Mazarini
Bonjour,

Sauf erreur de ma part, ca devrait marché un peu mieux :
while($file = readdir($dir)) {
    if($file != '.' && $file != '..' &&) {
      $source = $dirname.'/'.$file;
      !is_dir($source)) {
      {
            $tab_tmp = explode(".", $file);
            if (count($tab_tmp) == 2) {
               $nom_cible = $tab_tmp[0];
               $extension_cible = $tab_tmp[0];
               $cible =  $dirname . "/".strtolower(filter($nom_cible)).$extension_cible;
               if (file_exists($cible) {
                   echo "rename impossible le fichier existe déjà : ",$source,'=>',$cible,"<br>\n";    
               } else {
                  if (rename($source,$cible))
                      echo "rename OK : ",$source,'=>',$cible,"<br>\n";
                  } else {
                      echo "rename KO : ",$source,'=>',$cible,"<br>\n";
                 }
              }
            } else {
                 echo "source incorrecte (plusieurs .): ",$source,"<br>\n";
           }
           } else {
                echo "répertoire : ",$source,"<br>\n";
           }
      }    
 }
Edit :
1) ma solution ne marche que pour les fichiers avec un seul . et ne traite pas les sous-répertoires.
2) Moogli connais beaucoup mieux que moi les subtilités de PHP.

Re: Renommer fichiers

Posté : 05 oct. 2011, 16:49
par moogli
2) Moogli connais beaucoup mieux que moi les subtilités de PHP.
heu non, j'ai pris un bout de code que j'ai fait a partir de la doc parce que je trouvais soulant de devoir modifier l'extention des fichiers de mon site à la main juste pour changer de version de php (bon avant que je découvre que je pouvais changer la version utilisant l'extension .php dans l'interface que m'offre (enfin me loue plutot ^^) mon hébergeur :mrgreen: $

sinon n'étant pas sur mon ordi je ne peu tester le code fournit.

le !is_dir($source)) ne me plait pas (je ne sais pas si c'est fonctionnel, peux être j'en apprend tout les jours ;) ) mais un if me semble plus clair a la lecture ;)

@+

Re: Renommer fichiers

Posté : 05 oct. 2011, 16:52
par stealth35
pour l'extension c'est soit avec pathinfo soit avec getExtension :wink:

si y'a Intl ca sera plus propre avec le Normalizer pour renommer les fichiers

Re: Renommer fichiers

Posté : 05 oct. 2011, 17:11
par moogli
pour l'extension c'est soit avec pathinfo soit avec getExtension :wink:

si y'a Intl ca sera plus propre avec le Normalizer pour renommer les fichiers
voui tiens faudrait que je modifie mon code mici du rappel.

pour Intl j'ai pas encore trouvé l’intérêt si j'aimais t'a un bout de doc sur le sujet ça peux m'intéresser :mrgreen:

@+

Re: Renommer fichiers

Posté : 05 oct. 2011, 17:26
par stealth35
pour Intl j'ai pas encore trouvé l’intérêt si j'aimais t'a un bout de doc sur le sujet ça peux m'intéresser :mrgreen:

@+
$test = 'héhéhé';
$test = Normalizer::normalize($test, Normalizer::FORM_KD);
$test = preg_replace('/\p{Mn}+/u', '', $test);
echo $test;
// hehehe
après t'as l’outil pour les Traduction, et le formatage local de date et de nombre
un marrant :
$fmt = new NumberFormatter('fr', NumberFormatter::SPELLOUT );
echo $fmt->format(12345);
// douze-mille-trois-cent-quarante-cinq

Re: Renommer fichiers

Posté : 06 oct. 2011, 13:49
par baddev
Bonjour

Tout d'abord, un grand merci a vous tous. Votre aide m'a ete d'un grand secours. :D

Apres une fausse joie, je crois maintenant avoir un script qui fonctionne. J'ai fait un mix de vos propositions, ca donne ca :
<?php

/*
/ Script normalisant les noms de fichiers d'un repertoire donne
/ Renomme les doublons
*/

// Repertoire par defaut
$dirname = "";

// Extension par defaut (au cas ou le fichier n'en ai pas)
$default_ext = "";

$tab_file = array();
$list_cle = array();

$bytestotal = 0;
$nbfiles = 0;
$n = 0;

function filter($in) {
	$search = array ('@[éèêëÊË]@i','@[àâäÂÄ]@i','@[îïÎÏ]@i','@[ûùüÛÜ]@i','@[ôöÔÖ]@i','@[ç]@i','@[ ]@i','@[^a-zA-Z0-9_]@');
	$replace = array ('e','a','i','u','o','c','_','');
	return preg_replace($search, $replace, $in);
}

$dir_iterator = new RecursiveDirectoryIterator($dirname);

foreach (new RecursiveIteratorIterator($dir_iterator) as $current_file)
{
    if($current_file != '.' && $current_file != '..' && !is_dir($dirname.$current_file))
    {
        $filesize = $current_file->getSize();
        $bytestotal += $filesize;
        $nbfiles++;
        
        $path_parts = pathinfo($current_file);
        $dirname_cf = $path_parts['dirname'];    
        $filename_cf = $path_parts['filename'];
        (array_key_exists('extension', $path_parts)) ? $extension_cf = $path_parts['extension'] : $extension_cf = $default_ext;
        
        if(strtolower(filter($filename_cf)) != "") $pot_rename =  $dirname_cf . "/" . strtolower(filter($filename_cf)) . "." . $extension_cf;
        
        if(file_exists($pot_rename))
        {
            echo "rename impossible, the file already exists : " . $current_file . " => " . $pot_rename . "\n";
            rename($current_file, $dirname_cf . "/" . strtolower(filter($filename_cf)) . "_" . $n . "." . $extension_cf);
            $n++;
        } else
        {
            if($current_file != ".")
            {
                rename($current_file, $pot_rename);
                echo "rename OK : " . $current_file . " => " . $pot_rename . "\n";
            } else
            {
                echo "A problem occured with this file : " . $current_file . "\nYou should verify your files, the script's exiting..\n\n";
                exit(1);
            }
        }
    }
}

// End of script
$bytestotal = number_format($bytestotal);
echo "\n\nTotal: $nbfiles files, $bytestotal bytes \n\n";


?>
C'est loin d'etre parfait mais ca fonctionne : ca renomme tous les fichiers (dans tous les cas de figures.. je crois :roll: ) et renomme aussi les doublons (independamment des extensions).

Par contre, je n'ai pas compris comment instancier Normalizer et j'ai aucune idee de ce que veut dire : '/\p{Mn}+/u'.. Si vous avex des idees pour l'ameliorer, n'hesitez pas ! :)

Encore merci ! ;)

Re: Renommer fichiers

Posté : 06 oct. 2011, 14:13
par Mazarini
@Moogli : je manque cruellement de culture concernant les trucs genre RecursiveIteratorIterator, j'ai la mauvaise habitude de réinventer la roue à chaque fois pour ce genre de chose. Au fil de mes lectures sur ce site, je me rends compte que tout une partie de PHP me manque comme les fonctions sur les tableaux. A ma décharge, je m'en passe très bien et j'en apprends tous les jours quand même. A ma décharge également, j'ai appris le PHP à partir des sources de PHPNUKE...

Re: Renommer fichiers

Posté : 06 oct. 2011, 14:48
par sirakawa
Et moi à partir de rien...
Mais la lecture de la doc, si mal faite soit-elle, encombrée des délires de programmeurs dont on ignore en général ce qu'ils font de la fonction qu'ils commentent et encore plus de la fonction qu'ils proposent, parfois juste (je suppose qu'elle fonctionne dans certains cas, mais j'ai l'expérience d'une bibliothèque fortran =>C qui proposait une pseudo inversion de matrices non-carrées qu'un étudiant désespéré me soumit: l'exemple fonctionnait, pas son appliacation, quand nous découvrimes que l'exemple était trafiqué... et la fonction, fort couteuse, inutilisable...)...

Re: Renommer fichiers

Posté : 06 oct. 2011, 15:05
par stealth35
if($current_file != '.' && $current_file != '..' && !is_dir($dirname.$current_file))
c'est isDot et isDir, faut lire la doc de temps en temps ca coute rien d’être curieux

Re: Renommer fichiers

Posté : 06 oct. 2011, 17:03
par baddev
if($current_file != '.' && $current_file != '..' && !is_dir($dirname.$current_file))
c'est isDot et isDir, faut lire la doc de temps en temps ca coute rien d’être curieux
Merci pour tes suggestions : c'est vrai qu'apres une vingtaine de pages, j'avais un peu decroche. Je les avais loupe : my bad ! :roll:

En fait, normalizer retournait un not found : intl n'etait pas installer ! :lol:

La version 2.0 sera pour demain.. 8-)

Re: Renommer fichiers

Posté : 07 oct. 2011, 11:24
par baddev
Voila la derniere mouture, le script fait ce qu'il doit faire et non plus par hasard.. Ce qui est un peu (voire beaucoup..) mieux, je reconnais. :)
<?php

/*
/ Script normalisant les noms de fichiers d'un repertoire donne
/ Renomme les doublons
*/

$dirname = "mypath";
$default_ext = "myextension";

$tab_files = array();
$list_double_key = array();

$bytestotal = 0;
$nbfiles = 0;
$n = 0;

function filter($in) {
	$search = array ('@[éèêëÊË]@i','@[àâäÂÄ]@i','@[îïÎÏ]@i','@[ûùüÛÜ]@i','@[ôöÔÖ]@i','@[ç]@i','@[ ]@i','@[^a-zA-Z0-9_]@');
	$replace = array ('e','a','i','u','o','c','_','');
	return preg_replace($search, $replace, $in);
}


try
{
    $iterator = new DirectoryIterator($dirname);
    
    foreach($iterator as $current_file)
    {
        if(!$current_file->isDot() && !$current_file->isDir())
        {
            // infos on $current_file
            $path_parts = pathinfo($current_file);
            $filename_cf = $path_parts['filename'];

            // register all filenames and extensions in an array for the doublet treatment
           $tab_files[] = $filename_cf;
        }
    }

    // write the doublets array
    $count = array_count_values(array_map('strtolower', $tab_files));
    foreach($count as $key=>$value)
    {
        if($value > 1)
        {
            $list_double_key[$key] = $value;
            //echo "nom = " . $key . " et nombre d'occurences = " . $value . "\n";
        }
    }
    
    foreach($iterator as $current_file)
    {
        if(!$current_file->isDot() && !$current_file->isDir())
        {
            // count files and their weight
            $filesize = $current_file->getSize();
            $bytestotal += $filesize;
            $nbfiles++;
            
            // infos on $current_file
            $path_parts = pathinfo($current_file);
            $filename_cf = $path_parts['filename'];
            // test if file has an extension, if not assign the default one        
            (array_key_exists('extension', $path_parts)) ? $extension_cf = $path_parts['extension'] : $extension_cf = $default_ext;
            
            // test if normalized filename is empty
            if(strtolower(filter($filename_cf)) != "") $pot_rename =  $dirname . strtolower(filter($filename_cf)) . "." . $extension_cf;
            
            if(file_exists($pot_rename))
            {
                // test renaming relevance
                $supposed_file = strtolower(filter($filename_cf)) . "." . $extension_cf;
                $supposedn_file = strtolower(filter($filename_cf)) . "_" . $n . "." . $extension_cf;
                if($supposed_file == $current_file)
                {
                    if(array_key_exists($filename_cf, $list_double_key))
                    {
                        echo "There is some other file with the same name but another extension : renaming !\n";
                        rename($dirname . $current_file, $dirname . "/" . $supposedn_file);
                        echo "\tactually rename to : " . $current_file . " => " . $supposedn_file . "\n";
                        $n++;
                    }else
                    {
                        echo $current_file . " is already normalized : nothing to do.\n";
                    }
                } else
                {
                    echo "rename impossible, the file already exists : " . $current_file . " => " . $supposed_file . "\n";
                    rename($dirname . $current_file, $dirname . "/" . $supposedn_file);
                    echo "\tactually rename to : " . $current_file . " => " . $supposedn_file . "\n";
                    $n++;
                }
            } else
            {
                rename($dirname . $current_file, $pot_rename);
                echo "rename OK : " . $current_file . " => " . strtolower(filter($filename_cf)) . "." . $extension_cf . "\n";
            }
        }
    }
    
    // End of script
    $bytestotal = number_format($bytestotal);
    echo "\n\nTotal: $nbfiles files, $bytestotal bytes \n\n";

} catch(Exception $e)
{
    echo "A problem occured : The script\'s exiting !";
}

?>
Un grand merci a stealth35 qui aura su repousse les limites de l'exigence ! :D

Re: Resolu : Renommer fichiers

Posté : 12 oct. 2011, 12:12
par stealth35
ça me parait bien compliquer tout ça,
t'as un exemple de liste de fichier en entrée avec la sortie que ça rend ?

Re: Resolu : Renommer fichiers

Posté : 12 oct. 2011, 12:42
par baddev
Avant :

00076079.jpg
1email.gif
ABOUT.BMP
action.gif
angeldivider.gif
angry.BMP
^&*$$%.gif

Apres :

00076079.jpg
_0.gif
1email.gif
about.BMP
action.gif
angeldivider.gif
angry.BMP

Si tu as plus simple, n'hesites pas : j'ai le developpement ouvert.. :D