[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: renommer en lot



On 2008-01-28 06:59 +0100, Jack.R wrote:
> On Mon, 28 Jan 2008 00:11:58 -0500
> Remys Morrissette <remysmorrissette@cgocable.ca> wrote:
>
> > j'ai une série de fichiers (+/- 25000)
> > 
> > exemple :
> > 
> > 0bf153bfa73346bafd4035908ff3a4fb.png       Wed Oct 24 00:16:57 2007
> > 0bf30ca8b401ab42ad9adc8327ce8ac7.png     Mon Sep 10 21:15:09 2007
> > acda647ce3d021a81e126f9ccc622139.png     Tue May 22 21:17:32 2007
> > ace127012b35f74f29bf58a82268a98b.png     Thu Apr 13 23:52:55 2006
> > e3e1602a552ffe15b446388239b9299d.png     Sun Apr 15 22:36:11 2007
> > e3e3e4449d314d7abae0d1bba0acdc91.png     Mon Sep 10 21:33:37 2007
> > 
> > 
> > que j'aimerais renommer de façon séquentiel
> > 
> > dans le genre 1, 2, 3, ...., 25000
> > 
> > ou encore, 01, 02, 03, ..., a1, a2, a3, ...., e...
> > 
> > avec l'ordre par date si possible.
> 
> Un petit script bash (non testé, donc travailler sur une copie des
> images)
> 
> #!/bin/sh
> count=0
> for item in `ls -t -r *.png`
> do
>   mv $item `printf "%06d" $count`.png
>   count=$(( $count + 1 ))
> done

Il y a au moins un problème avec ce script ; la liste des fichiers
à traiter doit tenir sur la ligne de commande. On aura plus de
chances d'aboutir en faisant :

  find . -name "*.png" -type f -printf '%T@ %p\n' |
    sort -n |
    awk '{ print "mv \"" $2 "\" " sprintf("%05d.png", NR) }' |
    sh

Le code ci-dessus suppose que a) aucun des noms de fichiers à
renommer ne contient de newlines ou autres métacaractères shell,
b) qu'aucun des nouveaux noms n'existent et c) il est acceptable
de lancer un process mv par fichier. Voici une autre méthode qui
n'a pas ces inconvénients :

  find . -name "*.png" -type f -print0 |
    grep -z '/[0-9a-f]\{32\}\.png$' |
    perl -we '$/ = "\0";
      while (defined ($pathname = <>)) {
        $pathname =~ s/\0$//;
        print "> $pathname\n";
        @s = stat $pathname;
        die "$pathname: $!\n" unless @s;
        push @files, [$s[9], $pathname];
      }
      @files = sort { $a->[0] <=> $b->[0] } @files;
      my $n = 0;
      foreach $f (@files) {
        $oldname = $f->[1]; 
        do {
          $n++;
          $newname = sprintf "%05d.png", $n;
        } while (-e $newname);
        print "$oldname -> $newname\n";
        rename $oldname, $newname
          or die "$oldname: cannot rename to $newname ($!)\n";
      }'

Ce programme n'est pas prévu pour être utilisé de façon
incrémentale ; s'il est lancé plusieurs fois dans le même
répertoire après ajout de nouveaux fichiers [0-9a-f]{32}.png,
les numéros attribués aux nouveaux fichiers ne correspondront pas
à l'ordre des mtime, sauf si le plus ancien fichier ajouté est
plus récent que le plus récent fichier renommé dans la passe
précédente. Donc, si on renomme les fichiers de décembre puis on
ajoute les fichiers de novembre, pas la peine d'espérer que le
script remettra tous les numéros dans l'ordre.

-- 
André Majorel <http://www.teaser.fr/~amajorel/>
Thanks to the Debian project for going to such lengths never to
disclose the email addresses of their users. Think of all the
spam we would get if they didn't !


Reply to: