logo Debian Debian Debian-France Debian-Facile Debian-fr.org Forum-Debian.fr Debian ? Communautés logo inclusivité

Debian-facile

Bienvenue sur Debian-Facile, site d'aide pour les nouveaux utilisateurs de Debian.

Vous n'êtes pas identifié(e).

#1 23-04-2015 11:22:45

cemoi
Membre
Distrib. : Debian 10 Buster et une SID
Noyau : Linux 4.19.0-9-amd64
(G)UI : XFCE
Inscription : 21-10-2008

[resolu] nettoyage de caractéres éè-,:' et autres sur une arbo

Bonjour,
volia mes problèmes: j'ai une arboressence de plusieurs milliers de fichiers et de plusieurs centaines de repertoires/sous repertoires avec parfois (pas trop mais il y en a...) des 'toto'atata.odt ou tata (1) blabla.pdf ou encore du lolo-lala.ods
ça c'est pour les fichiers...
Pour les repertoires il y a des espaces dans les noms du type: /foo 01/tata ops lulu/blalba toto lili tata/ébéçlàmemem.odt

Pour remplacer les espaces par des _ je fais:

find -type f -depth -name '*.*' -execdir rename 's/\s+/_/g' '{}' \;



ce n'es tcertainement pas parfait mais je ne sais pas programmer et je ne connais pas le shell... j'ai rtfm pendant quelques jours mais le temps me manque pour tout comprendre notament sur l'algo de tout ça. Je me suis surtout appuyé sur les man page.

Pour supprimer les éçèà j'ai tenté un;

find -type f -name '*.pdf' -execdir iconv -f utf8 -t ascii//TRANSLIT '{}' \;



mais ce n'est pas bon... je dois pas en être loin mais ce n'est pas encore ça....


Pour supprimer les _ consecutif genre toto__tata.odt

J'ai tenté un:

find -type f -name '*.*' -execdir sed -r 's/\s+/_/g' '{}' \;



Mais là encore il y a un problème dans l'algo (je pense) même si la commande sed va bien...

Il me faut trouver une solution pour remplacer les ( et ) par _

Quand tous ces petits script marcheront je verrai pour les ameliorer avec un coup de xargs par exemple...


Merci pour vos lumières!

Dernière modification par cemoi (25-04-2015 16:58:34)


Linux debDesk Linux 4.19.0-9-amd64

Hors ligne

#2 23-04-2015 13:06:06

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : [resolu] nettoyage de caractéres éè-,:' et autres sur une arbo

Salut,

Je te propose le script perl suivant :

#! /usr/bin/perl -CO
use utf8;

for (@ARGV) {
    $old_name=$_;
    s/\s+/_/g;
    s|/+|-|g;
    s/_([-:.,;])_/$1/g;
    s/_([-:.,;])/$1/g;
    s/([-:.,;])_/$1/g;
    s/[()]+/_/g;
    s/[éèëê]/e/g;
    s/[ÉÈÊË]/E/g;
    s/[àâä]/a/g;
    s/[ÀÂÄ]/A/g;
    s/[ïî]/i/g;
    s/[ÎÏ]/I/g;
    s/[öô]/o/g;
    s/[ÔÖ]/O/g;
    s/[üûù]/u/g;
    s/[ÛÜÙ]/U/g;
    s/œ/oe/g;
    s/æ/ae/g;
    s/Œ/OE/g;
    s/Æ/AE/g;
    s/_{2,}/_/g;

    if (! -e $_ and $_ ne '' ) {
       rename($old_name, $_) || warn("$!");
    } else {
        warn("Pas de renomage de : $old_name -> $_ : le fichier existe déjà\n");
    }


}
 


Ça ne sera peut être pas suffisant, mais c'est un début. Tu peux
rajouter des substitution dans la boucle.
Son usage, est assez simple, il essaye de renommer tous
les fichiers passer en argument. Si tu veux je peux l'améliorer en
ne renommant que le fichier final. Tel quel, il faut le rendre
exécutable et le mettre dans le PATH. J'ai décidé de l'appeler
« special-rename.pl » wink
Tu devras l'utiliser en le combinant avec find :


find -type f -depth -name '*.*' -execdir special-rename.pl '{}' \;
 


pour reprendre la commande que tu faisais.

EDIT: ATTENTION: Apparemment, la gestion de l'unicode dans perl n'est pas aussi simple
que je le pensais. Ce script ne fonctionne pas sad

Dernière modification par enicar (24-04-2015 13:04:38)

Hors ligne

#3 23-04-2015 14:16:35

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : [resolu] nettoyage de caractéres éè-,:' et autres sur une arbo

J'ai ajouté -CO au shebang car sinon perl n'affiche pas les caractères
utf8 sur STDOUT… La première ligne devient donc :

#! /usr/bin/perl -CO



Si le script est lancé avec :


perl special-rename.pl
 


perl va refuser de l'exécuter en disant

perl a écrit :


Too late for "-CO" option at special-rename.pl line 1.


Pour pouvoir le lancer il faut faire :


perl -CO special-rename.pl
 



Perl est pénible avec la gestion de l'utf8, j'aurai mieux fait de te mettre la même chose en
ruby… mais bon wink

ATTENTION: Les modifications apportées ne résolvent pas le problème.
Ce script ne fonctionne toujours pas.

Dernière modification par enicar (24-04-2015 13:06:09)

Hors ligne

#4 23-04-2015 23:05:15

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : [resolu] nettoyage de caractéres éè-,:' et autres sur une arbo

Finalement, mon script en perl est très loin de fonctionner. J'ai donc fait la même
chose en ruby, mais cette fois ça marche smile


#! /usr/bin/ruby
# encoding: UTF-8

ARGV.each { |old_name|
    t=String.new(old_name)
    t.gsub!(%r'[\x00-\x1f]', '')
    t.gsub!(%r' +', '_')
    t.gsub!(%r'/+', '-')
    t.gsub!(%r'_([-:.,;])_', '\1')
    t.gsub!(%r'_([-:.,;])', '\1')
    t.gsub!(%r'([-:.,;])_', '\1')
    t.gsub!(%r'-+', '-')
    t.gsub!(%r'[éèëê]', 'e')
    t.gsub!(%r'[ÉÈÊË]', 'E')
    t.gsub!(%r'[àâä]', 'a')
    t.gsub!(%r'[ÀÂÄ]', 'A')
    t.gsub!(%r'[ïî]', 'i')
    t.gsub!(%r'[ÏÎ]', 'I')
    t.gsub!(%r'[öô]', 'o')
    t.gsub!(%r'[ÖÔ]', 'O')
    t.gsub!(%r'[üûù]', 'u')
    t.gsub!(%r'[ÜÛÙ]', 'U')
    t.gsub!(%r'_{2,}', '_')
    if t != '' and ! File.exist?(t)
        begin
            File.rename old_name, t
        rescue SystemCallError => err
            $stderr.print "impossible de renomer #{old_name} en #{t}: #{err}\n"
        end
    else
        $stderr.print "Pas de renommage de #{old_name} en #{t}\n"
    end
}
 


Même usage que pour le script en perl, sauf que lui fonctionne car il gère correctement
l'utf8 !
Pour le script en perl, il va falloir que je cherche pour trouver comment lui faire
comprendre ce que je veux faire avec l'utf8 wink

EDIT: ATTENTION utiliser le script du post #7, celui-ci, comporte
des erreurs et des lacunes.

Dernière modification par enicar (24-04-2015 13:07:48)

Hors ligne

#5 24-04-2015 06:51:51

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : [resolu] nettoyage de caractéres éè-,:' et autres sur une arbo

J'ai changé :

rescue SystemError => err


en

rescue SystemCallError => err


Dans le post précédent. En effet, SystemError, n'existe pas tongue

Hors ligne

#6 24-04-2015 08:53:38

cemoi
Membre
Distrib. : Debian 10 Buster et une SID
Noyau : Linux 4.19.0-9-amd64
(G)UI : XFCE
Inscription : 21-10-2008

Re : [resolu] nettoyage de caractéres éè-,:' et autres sur une arbo

bon comme la nuit porte conseil voila un script bash quivabien mais qui resou pas tout...

#!/bin/bash
IFS="|"
if [ $# -lt 1 ]
then
echo "Usage: `basename $0` <file(s)>"
fi
for file in $@
do
        newName=`echo "$file" | unaccent UTF-8`
        if [ $newName != $file ]; then
                echo "$file=>$newName"
                mv "$file" "$newName"
        fi
done



je met le script dans ~/bin et je fais un chmod u+x sur le fichier que je nomme unaccent-file

Attention il faut mettre ~/bin dans le PATH

de là je me sers du machin de cette façon;


unaccent-file fichier1 fichier2 ...


pour un fichier ou deux

pour traiter tout ce qui est dans le repertoir courant:

find . -exec unaccent-file '{}' \;



Pour toute l'arboressence seulement sur les fichiers:

find -type f -exec unaccent-file '{}' \+



J'ai encore des problèmes mais ça degrossi serieusement!

j'ai des problèmes avec les fichiers qui contiennent des - je pourrais ragler le pb en les supprimant avec un coup de sed non?
les mesages d'erreures sont du type;
mv: impossible d'évaluer « ./Machines outils/Permis C - Mortaiseuse/Document sur la mortaiseuse a bedane/Procédure machine/Mortaiseuse_à_bédane.pdf »: Aucun fichier ou dossier de ce type

Forcément avec des - dans le nom des répertoires...:mad:

Comme il m'en reste tres peu à gérer je pense que je vais terminer ça à la main...car c'est pour demain!

Dernière modification par cemoi (24-04-2015 08:55:42)


Linux debDesk Linux 4.19.0-9-amd64

Hors ligne

#7 24-04-2015 09:56:13

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : [resolu] nettoyage de caractéres éè-,:' et autres sur une arbo

Suite à notre discussion sur irc, voici une nouvelle version du script
en ruby, qui sera plus proche de tes besoins :


#! /usr/bin/ruby
# encoding: UTF-8

ARGV.each { |old_name|
    t=String.new(old_name)
    t.gsub!(%r'[\x00-\x1f]', '')
    t.gsub!(%r' +', '_')
    t.gsub!(%r'_([-:.,;])_', '\1')
    t.gsub!(%r'_([-:.,;])', '\1')
    t.gsub!(%r'([-:.,;])_', '\1')
    t.gsub!(%r'-+', '-')
    t.gsub!(%r'[()]+', '_')
    t.gsub!(%r"'", '')
    t.gsub!(%r'[éèëê]', 'e')
    t.gsub!(%r'[ÉÈÊË]', 'E')
    t.gsub!(%r'[àâä]', 'a')
    t.gsub!(%r'[ÀÂÄ]', 'A')
    t.gsub!(%r'[ïî]', 'i')
    t.gsub!(%r'[ÏÎ]', 'I')
    t.gsub!(%r'[öô]', 'o')
    t.gsub!(%r'[ÖÔ]', 'O')
    t.gsub!(%r'[üûù]', 'u')
    t.gsub!(%r'[ÜÛÙ]', 'U')
    t.gsub!(%r'_{2,}', '_')
    t.gsub!(%r'œ','oe')
    t.gsub!(%r'æ','ae')
    t.gsub!(%r'Œ','OE')
    t.gsub!(%r'Æ','AE')
    t.gsub!(%r'Ç', 'C')
    t.gsub!(%r'ç', 'c')
    if t != '' and not File.exist?(t)
        begin
            File.rename old_name, t
            # print "#{old_name} -> #{t}\n"
        rescue SystemCallError => err
            $stderr.print "impossible de renomer #{old_name} en #{t}: #{err}\n"
        end
    else
        $stderr.print "Pas de renommage de #{old_name} en #{t}\n"
    end
}
 



Alors, pour l'utiliser, je suggére :


find -depth -type f -name '*.*' -execdir special-rename.rb '{}' \;
 



L'option -execdir de find est important ici, car sinon les
conversion sont appliquées aux  chaines passées en argument
de manière globale. Autrement dit le script ne cherche pas à isoler
le basename pour ne travaille que sur lui. Ça serait facile
de le faire, mais bon…

J'ai laissé une ligne en commentaire qui permet de faire des tests.
Pour voir comment le script transforme les noms il suffit de remplacer
les lignes :


begin
    File.rename old_name, t
    # print "#{old_name} -> #{t}\n"
rescue SystemCallError => err
 


par :


begin
    # File.rename old_name, t
    print "#{old_name} -> #{t}\n"
rescue SystemCallError => err
 


Voilà wink

Dernière modification par enicar (24-04-2015 10:21:15)

Hors ligne

#8 24-04-2015 11:14:09

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : [resolu] nettoyage de caractéres éè-,:' et autres sur une arbo

Bon, j'ai fait un script sed qui permet de convertir ou supprimé
quelques caractères, Je l'ai appelé special-sub wink


#! /usr/bin/sed -f
s/ \+/_/g
s/[()]\+/_/g
s/'//g
s/"//g
s/-\{2,\}/-/
s/_\{2,\}/_/
 


Il transforme les espaces en _, supprime les ' et les ", et
les _ (respect.  -) contigüe par un seul _ (respect. -), les
parenthèses sont transformées en _. Il fonctionne avec Gnu sed,
pour les autres sed, je ne sais pas. Dans debian, on utilise
Gnu sed, aussi bien…

Pour l'utiliser :


echo "'_(__'-)-" |sed -f special-sub
 


nous retourne :


_-_-
 



Pour le mettre dans ton code, tu peux le mettre dans ~/bin et
le rendre exécutable. De cette façon dans ton script unaccent-file
ça donnerait :


#!/bin/bash

if [ $# -lt 1 ]
then
    echo "Usage: `basename $0` <file(s)>"
fi

for file in "$@"
do
        newName="$(echo $file |unaccent UTF-8)"
        newName="$(echo $newName |special-sub)"
        if [ "$newName" != "$file" ]; then
                echo "$file=>$newName"
                mv "$file" "$newName"
        fi
done
 


J'ai modifié un peu ton script, j'espère que ça n'intrdoduira pas
de bug…

EDIT: J'ai rajouté des " autour des variables dans le test « if [ "$newName" != "$file" ] »
car sinon ça ne gère pas les noms avec des espaces. En effet, si $newName ne contient
plus d'espaces, ce n'est pas le cas de $file.

EDIT 2: Pour l'utiliser, il faut utiliser l'option -execdir de find, pour les mêmes raisons que
le script du post #7 en ruby.

Dernière modification par enicar (24-04-2015 13:10:02)

Hors ligne

#9 24-04-2015 18:00:34

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : [resolu] nettoyage de caractéres éè-,:' et autres sur une arbo

Bon, nouvelle version de special-rename.rb qui supprime
les caractères « ' " ? * : ? ; , ».


#! /usr/bin/ruby
# encoding: UTF-8

ARGV.each { |old_name|
    t=File.basename(old_name)
    d=File.dirname(old_name)
    t.gsub!(%r'[[:cntrl:]]', '')
    t.gsub!(%r'[[:space:]]+', '_')
    t.gsub!(%r'-+', '_')
    t.gsub!(%r'[()]+', '_')
    t.gsub!(%r"['\"?*:,;]", '')
    t.gsub!(%r'[éèëê]', 'e')
    t.gsub!(%r'[ÉÈÊË]', 'E')
    t.gsub!(%r'[àâä]', 'a')
    t.gsub!(%r'[ÀÂÄ]', 'A')
    t.gsub!(%r'[ïî]', 'i')
    t.gsub!(%r'[ÏÎ]', 'I')
    t.gsub!(%r'[öô]', 'o')
    t.gsub!(%r'[ÖÔ]', 'O')
    t.gsub!(%r'[üûù]', 'u')
    t.gsub!(%r'[ÜÛÙ]', 'U')
    t.gsub!(%r'œ','oe')
    t.gsub!(%r'æ','ae')
    t.gsub!(%r'Œ','OE')
    t.gsub!(%r'Æ','AE')
    t.gsub!(%r'Ç', 'C')
    t.gsub!(%r'ç', 'c')
    t.gsub!(%r'_{2,}', '_')
    new_name=d + '/' + t
    if new_name != old_name and t != '' and not File.exist?(new_name)
        begin
            File.rename old_name, new_name
            # print "#{old_name} -> #{new_name}\n"
        rescue SystemCallError => err
            $stderr.print "impossible de renomer #{old_name} en #{new_name}: #{err}\n"
        end
    else
        $stderr.print "Pas de renommage de #{old_name} en #{new_name}\n"
    end
}

 


Même usage que précédemment. Sauf, que le l'option -execdir de find
n'est plus requise.

EDIT: J'ai modifié le script pour qu'il gère mieux les caractères d'espacements.

Dernière modification par enicar (24-04-2015 20:00:17)

Hors ligne

#10 24-04-2015 19:49:08

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : [resolu] nettoyage de caractéres éè-,:' et autres sur une arbo

Et je te propose une nouvelle version du script sed, special-sub :


#! /usr/bin/sed -f
s/[[:cntrl:]]\+//g
s/[[:space:]]\+/_/g
s/[()]\+/_/g
s/['"?;,]//g
s/-\+/_/g
s/_\{2,\}/_/g
 


Il correspondra mieux à ce que tu attends wink

Et j'ai amélioré ton script bash, unaccent-file :


#!/bin/bash

set -e
set -u

if [ $# -lt 1 ]
then
    echo "Usage: `basename $0` <file(s)>"
fi

for file in "$@"
do
        t=$(basename -- "$file")
        d=$(dirname -- "$file")
        t="$(echo $t |unaccent UTF-8)"
        t="$(echo $t |special-sub)"
        newName="${d}/${t}"
        if [ "$newName" != "$file" ] &&
           [ -n "$t" ] &&
           [ ! -e "$newName" ]      
       then
                echo "$file=>$newName"
                mv -- "$file" "$newName"
        fi
done
 


Comme ça, il est sensé se comporter comme le script ruby…
D'après le test succinct que j'ai réalisé, ça semble fonctionner.

Hors ligne

#11 24-04-2015 21:23:01

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : [resolu] nettoyage de caractéres éè-,:' et autres sur une arbo

Après la version en ruby et en shell, voici une version en python3. Le
script ne fonctionne pas avec python2. Je l'ai appelé
special-rename.py, bien sûr wink


#! /usr/bin/python3
# vim: fileencoding=utf-8
# le commentaire précédent est en réalité pour python, et non pour vim !

from re import sub
from sys import argv
from os import rename, path

# Peut être faudrait-il compiler toutes les regexps pour gagner
# en performance.
def special_sub(old_name):
    new_name = sub(r"[[:cntrl:]]", '', old_name)
    new_name = sub(r"[[:space:]]+", '_', new_name)
    new_name = sub(r"-+", '_', new_name)
    new_name = sub(r"[()]+", '_', new_name)
    new_name = sub(r"['\"?*:,;]", '', new_name)
    new_name = sub(r"[éèëê]", 'e', new_name)
    new_name = sub(r"[ÉÈÊË]", 'E', new_name)
    new_name = sub(r"[àâä]", 'a', new_name)
    new_name = sub(r"[ÀÂÄ]", 'A', new_name)
    new_name = sub(r"[ïî]", 'i', new_name)
    new_name = sub(r"[ÏÎ]", 'I', new_name)
    new_name = sub(r"[öô]", 'o', new_name)
    new_name = sub(r"[ÖÔ]", 'O', new_name)
    new_name = sub(r"[üûù]", 'u', new_name)
    new_name = sub(r"[ÜÛÙ]", 'U', new_name)
    new_name = sub(r"œ",'oe', new_name)
    new_name = sub(r"æ",'ae', new_name)
    new_name = sub(r"Œ",'OE', new_name)
    new_name = sub(r"Æ",'AE', new_name)
    new_name = sub(r"Ç", 'C', new_name)
    new_name = sub(r"ç", 'c', new_name)
    new_name = sub(r"_{2,}", '_', new_name)
    return new_name


# supprime le nom du script du tableau argv, seul les arguments
# m'intéresse ici.
argv.pop(0)
for old_name in argv:
    t = path.basename(old_name)
    d = path.dirname(old_name)
    t = special_sub(t)
    if d == '':
        new_name = t
    else:
        new_name = d + '/' + t
    try:
        if old_name != new_name and t != '' and not path.exists(new_name):
            rename(old_name, new_name)
            #print("{0} -> {1}".format(old_name, new_name))
        else:
            print("Impossible de renomer {0} en {1}".format(old_name, new_name))
    except OSError:
        print("Impossible de renommer {0} en {1}".format(old_name, new_name))
 



Même usage que le script en ruby.

Le problème avec python 2.7, c'est que si on essaye de remplacer
la chaine "é" par "e", on obtient "ee". Il y a d'autres bizarreries
comme pour le symbole "€" qui est convertit en "¬", alors que je n'ai
rien fait pour cela… Il doit bien exister une façon de faire la même tâche
avec python 2.7, et je serai  curieux de savoir comment.


EDIT: ATTENTION J'ai été un peu optimiste. Python  ne reconnaît pas les classes de caractères posix dans les regexps. Donc ce script, ne fonctionne pas, car j'ai utilisé [:cntrl:] et [:space:].
Utilisez, la version du post #15, à la place.

Dernière modification par enicar (25-04-2015 14:08:28)

Hors ligne

#12 24-04-2015 21:45:40

Papadakis
Membre
Lieu : Far ouest environ
Distrib. : Bookworm
Noyau : Linux 6.1.0-9-amd64
(G)UI : xfce 4.18
Inscription : 23-04-2014

Re : [resolu] nettoyage de caractéres éè-,:' et autres sur une arbo

Il doit me manquer des modules python, ça ne fait strictement rien chez moi.

Le désordre, c'est l'ordre, moins le pouvoir.

Hors ligne

#13 24-04-2015 22:01:27

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : [resolu] nettoyage de caractéres éè-,:' et autres sur une arbo

Papadakis a écrit :

Il doit me manquer des modules python, ça ne fait strictement rien chez moi.



Si tu lances ces scripts sans arguments, il ne font rien.
Ils sont faits pour être utilisés avec find.

Hors ligne

#14 25-04-2015 07:11:38

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : [resolu] nettoyage de caractéres éè-,:' et autres sur une arbo

J'aurai du être plus précis. La commande find avec laquelle ces script sont censés être utilisés est :


find -depth -type f -name <motif> -execdir <script> '{}' \;
 


On peut l'utiliser  pour des répertoire, ne pas utiliser l'option -name, utiliser -exec à la place de -execdir pour
les dernières versions. Pour renommer des répertoires dans une arborescence, il est important de garder
l'option -depth. On peut aussi, faire traiter plusieurs fichiers d'un seul coup par un script, en pseudo
code, ça donnerait :


find -depth [-type f|d] [-name <motif>] -exec|-execdir <script> '{}' +
 


Les expressions entre [ ] sont facultatives, les | expriment une alternative. <motif> est un motif du shell,
<script> est le nom d'un script.

EDIT: J'avais encore oublié le '{}' pour l'argument du script tongue

Dernière modification par enicar (25-04-2015 13:09:33)

Hors ligne

#15 25-04-2015 14:04:46

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : [resolu] nettoyage de caractéres éè-,:' et autres sur une arbo

Version corrigée du script du post #11, celle-ci devrait fonctionner correctement wink


#! /usr/bin/python3
# -*- coding: utf-8 -*-

from re import sub
from sys import argv
from os import rename, path

# Peut être faudrait-il compiler toutes les regexps pour gagner
# en performance.
def special_sub(old_name):
    new_name = sub('[\x00-\x19\x7F]', '', old_name)
    new_name = sub(r'\s+', '_', new_name)
    new_name = sub(r"-+", '_', new_name)
    new_name = sub(r"[()]+", '_', new_name)
    new_name = sub(r"['\"?*:,;]", '', new_name)
    new_name = sub(r"[éèëê]", 'e', new_name)
    new_name = sub(r"[ÉÈÊË]", 'E', new_name)
    new_name = sub(r"[àâä]", 'a', new_name)
    new_name = sub(r"[ÀÂÄ]", 'A', new_name)
    new_name = sub(r"[ïî]", 'i', new_name)
    new_name = sub(r"[ÏÎ]", 'I', new_name)
    new_name = sub(r"[öô]", 'o', new_name)
    new_name = sub(r"[ÖÔ]", 'O', new_name)
    new_name = sub(r"[üûù]", 'u', new_name)
    new_name = sub(r"[ÜÛÙ]", 'U', new_name)
    new_name = sub(r"œ",'oe', new_name)
    new_name = sub(r"æ",'ae', new_name)
    new_name = sub(r"Œ",'OE', new_name)
    new_name = sub(r"Æ",'AE', new_name)
    new_name = sub(r"Ç", 'C', new_name)
    new_name = sub(r"ç", 'c', new_name)
    new_name = sub(r"_{2,}", '_', new_name)
    return new_name


# supprime le nom du script du tableau argv, seul les arguments
# m'intéresse ici.
argv.pop(0)
for old_name in argv:
    t = path.basename(old_name)
    d = path.dirname(old_name)
    t = special_sub(t)
    if d == '':
        new_name = t
    else:
        new_name = d + '/' + t
    try:
        if old_name != new_name and t != '' and not path.exists(new_name):
            rename(old_name, new_name)
            #print("{0} -> {1}".format(old_name, new_name))
        else:
            print("Impossible de renomer {0} en {1}".format(old_name, new_name))
    except OSError:
        print("Impossible de renommer {0} en {1}".format(old_name, new_name))
 

Dernière modification par enicar (25-04-2015 14:09:27)

Hors ligne

#16 26-04-2015 11:28:11

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : [resolu] nettoyage de caractéres éè-,:' et autres sur une arbo

J'ai réalise une nouvelle version du script python
special-rename.py. Elle est plus « pythonesque ». Finalement
on compile toutes les regexps, pour gagner en efficacité. Quand on
l'utilise sans arguments, le script affiche son usage et sort avec
un code de sortie non nul. Comme ça, ça sera plus clair.
Donc voici le script :


#! /usr/bin/python3
# -*- coding: utf-8 -*-

import re
from sys import argv, exit
import os
from os import rename, path

def special_sub(regexps, old_name):
    """regexps est le dictionnaire calculé par compile_regexps().
old_name esst une chaine de caractère unicode.
Retourne une nouvelle chaine qui correspond à l'application des
transformations des du dictionnaire regexps sur la chaine old_name."""

    new_name=old_name
    for k, v in regexps.items():
        if k != 'underscore':
            reg, repl=v
            new_name=reg.sub(repl, new_name)
    reg, repl=regexps['underscore']
    new_name=reg.sub(repl, new_name)
    return new_name

def compile_regexps():
    """Retourne un dictionnaire, les clefs sont les noms qui correspondent
à une regexp compilée. La valeur est un tuple de la regexp compilée et
de la chaine de remplacement"""

    dico={
        'cntrl': ('[\x00-\x19\x7F]', ''),
        'space': (r'\s+', '_'),
        'minus': (r"-+", '_'),
        'paren': (r"[()]+", '_'),
        'punct': (r"['\"?*:,;!]", ''),
        'e': (r"[éèëê]", 'e'),
        'e_caps': (r"[ÉÈÊË]", 'E'),
        'a': (r"[àâä]", 'a'),
        'a_caps': (r"[ÀÂÄ]", 'A'),
        'i': (r"[ïî]", 'i'),
        'i_caps': (r"[ÏÎ]", 'I'),
        'o': (r"[öô]", 'o'),
        'o_caps': (r"[ÖÔ]", 'O'),
        'u': (r"[üûù]", 'u'),
        'u_caps': (r"[ÜÛÙ]", 'U'),
        'oe': (r"œ",'oe'),
         'oe_caps': (r"Œ",'OE'),
        'ae': (r"æ",'ae'),
        'ae_caps': (r"Æ",'AE'),
        'c': (r"Ç", 'C'),
        'c_caps': (r"ç", 'c'),
        'underscore': (r"_{2,}", '_'),
        }
    regexps=dict()
    for k, v in dico.items():
        s, repl=v
        regexps[k]=(re.compile(s, re.UNICODE), repl)
    return regexps
   
def usage():
    print("usage: {0} file [files…]".format(argv[0]))
    exit(1)

#### MAIN

if len(argv) == 1:
    usage()
# supprime le nom du script du tableau argv, seul les arguments
# m'intéresse ici.
argv.pop(0)
# précompile toutes les regexp
regexps=compile_regexps()
for old_name in argv:
    t = path.basename(old_name)
    d = path.dirname(old_name)
    t = special_sub(regexps,t)
    if len(d) == 0:
        new_name = t
    else:
        new_name = os.sep.join([d, t])
    try:
        if old_name != new_name and len(t) != 0 and not path.exists(new_name):
            rename(old_name, new_name)
            #print("{0} -> {1}".format(old_name, new_name))
        else:
            print("Impossible de renomer {0} en {1}".format(old_name, new_name))
    except OSError:
        print("Impossible de renommer {0} en {1}".format(old_name, new_name))
 


Voilà, d'après les quelques tests que j'ai faits, ça fonctionne.

EDIT: Au fait, c'est toujours du python3, désolé pour les utilisateurs python 2, je n'ai pas trouvé
de façon satisfaisante de le faire.

EDIT2 J'avais oublié le ! dans les caractères de ponctuations, je l'ai rajouté.

Dernière modification par enicar (26-04-2015 11:54:04)

Hors ligne

#17 26-04-2015 15:03:28

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : [resolu] nettoyage de caractéres éè-,:' et autres sur une arbo

Nouvelle version en ruby. Rajout du ! dans les ponctuations à
supprimer. Le script affiche l'usage, quand il est appelé sans
arguments. Quelques modifications pour être plus portable.


#! /usr/bin/ruby
# encoding: UTF-8

def usage()
    $stderr.print "usage: #{$0} file [files…]\n"
    exit 1
end

if ARGV.size == 0
    usage()
end

ARGV.each { |old_name|
    t=File.basename(old_name)
    d=File.dirname(old_name)
    t.gsub!(%r'[[:cntrl:]]', '')
    t.gsub!(%r'[[:space:]]+', '_')
    t.gsub!(%r'-+', '_')
    t.gsub!(%r'[()]+', '_')
    t.gsub!(%r"['\"?*:,;!]", '')
    t.gsub!(%r'[éèëê]', 'e')
    t.gsub!(%r'[ÉÈÊË]', 'E')
    t.gsub!(%r'[àâä]', 'a')
    t.gsub!(%r'[ÀÂÄ]', 'A')
    t.gsub!(%r'[ïî]', 'i')
    t.gsub!(%r'[ÏÎ]', 'I')
    t.gsub!(%r'[öô]', 'o')
    t.gsub!(%r'[ÖÔ]', 'O')
    t.gsub!(%r'[üûù]', 'u')
    t.gsub!(%r'[ÜÛÙ]', 'U')
    t.gsub!(%r'œ','oe')
    t.gsub!(%r'æ','ae')
    t.gsub!(%r'Œ','OE')
    t.gsub!(%r'Æ','AE')
    t.gsub!(%r'Ç', 'C')
    t.gsub!(%r'ç', 'c')
    t.gsub!(%r'_{2,}', '_')
    new_name=[d, t].join(File::Separator)
    if new_name != old_name and t.size != 0 and not File.exist?(new_name)
        begin
            File.rename old_name, new_name
            #print "#{old_name} -> #{new_name}\n"
        rescue SystemCallError => err
            $stderr.print "impossible de renomer #{old_name} en #{new_name}: #{err}\n"
        end
    else
        $stderr.print "Pas de renommage de #{old_name} en #{new_name}\n"
    end
}
 


Voilà, les versions en ruby et en python font la même chose smile

Hors ligne

#18 26-04-2015 15:14:44

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : [resolu] nettoyage de caractéres éè-,:' et autres sur une arbo

Nouvelle version du script sed special-sub


#! /usr/bin/sed -f
s/[[:cntrl:]]\+//g
s/[[:space:]]\+/_/g
s/[()]\+/_/g
s/['"?;,!]//g
s/-\+/_/g
s/_\{2,\}/_/g
 



J'ai modifié le script bash avec lequel l'utilisé, pour que les
trois versions se ressemblent :


#!/bin/bash

#set -e
#set -u

if [ $# -lt 1 ]
then
    echo "Usage: `basename $0` <file(s)>" >&2
    exit 1
fi

for file in "$@"
do
        t=$(basename -- "$file")
        d=$(dirname -- "$file")
        t="$(echo $t |unaccent UTF-8)"
        t="$(echo $t |special-sub)"
        newName="${d}/${t}"
        if [ "$newName" != "$file" ] &&
           [ -n "$t" ] &&
           [ ! -e "$newName" ]      
       then
                #echo "$file=>$newName"
                mv -- "$file" "$newName"
        else
            echo "Pas de renommage de ${file} en ${newName}" >&2
        fi
done
 

Hors ligne

#19 26-04-2015 16:52:19

Thuban
aka prx
Distrib. : OpenBSD
Noyau : current
(G)UI : cwm
Inscription : 09-01-2009
Site Web

Re : [resolu] nettoyage de caractéres éè-,:' et autres sur une arbo

De beaux script que voilà!
Cependant, je me demande, le paquet "detox" ne faisait pas déjà tout ça? (detox -r permet de corriger les noms de fichiers de façon récursive en plus)

Hors ligne

#20 26-04-2015 18:43:24

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : [resolu] nettoyage de caractéres éè-,:' et autres sur une arbo

Et c'est maintenant que tu te manifestes ? big_smile

Enfin pas grave, l'avantage de mes scripts, c'est que l'on peut les adapter à
un usage particulier que ne fait pas detox. Et d'ailleurs, c'est le cas car ces scripts
transforme les - en _ et compacte les _ consécutifs. Ce n'est pas courant comme
transformation. C'est ce que voulez cemoi…

Hors ligne

#21 26-04-2015 19:03:15

Thuban
aka prx
Distrib. : OpenBSD
Noyau : current
(G)UI : cwm
Inscription : 09-01-2009
Site Web

Re : [resolu] nettoyage de caractéres éè-,:' et autres sur une arbo

enicar a écrit :

Et c'est maintenant que tu te manifestes ? big_smile


Ben... j'ai un peu de mal ces temps-ci à maintenir mon activité sur la toile... hmm

Hors ligne

#22 26-04-2015 19:07:09

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : [resolu] nettoyage de caractéres éè-,:' et autres sur une arbo

Thuban a écrit :


Ben... j'ai un peu de mal ces temps-ci à maintenir mon activité sur la toile... hmm


Ce n'est pas grave, je te taquinais, hein wink
Moi, je me suis bien amusé à faire ces scripts, et ça m'a permis d'apprendre python smile

Hors ligne

#23 26-04-2015 19:43:01

cemoi
Membre
Distrib. : Debian 10 Buster et une SID
Noyau : Linux 4.19.0-9-amd64
(G)UI : XFCE
Inscription : 21-10-2008

Re : [resolu] nettoyage de caractéres éè-,:' et autres sur une arbo

haha et moi ça m'a permis d'apprendre encore un peu plus... et de passer à la moulinettes quelques dizaines de milliers de fichiers smile
Le script en shell permet de ne rien installé de plus quand c'est sur un serveur c'est appréciable. Sans parler que certains serveurs peuvent être sur une ancienne version de debian...
Je ne sais pas ce que fait detox exactement mais avec les script il y a moyen d'adapté du genre travailler que sur un type d'extension ou juste sur des nom de fichiers contenant certains mots dedans. Ca permet aussi de travailler que sur les répertoires ou que sur les fichiers.
Je regarderai detox quand même pour ma culture :]

Dernière modification par cemoi (26-04-2015 19:52:16)


Linux debDesk Linux 4.19.0-9-amd64

Hors ligne

#24 26-04-2015 19:45:58

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : [resolu] nettoyage de caractéres éè-,:' et autres sur une arbo

cemoi a écrit :

Je ne sais pas ce que fait detox exactement mais avec les script il y a moyen d'adapté du genre travailler que sur un type d'extension ou juste sur des nom de fichiers contenant certains mots dedans.
Je regarderai detox quand même pour ma culture :]



C'est possible aussi avec detox aussi, en passant par find, ou autre… Quant à savoir ce qu'il fait exactement c'est décrit dans des tables de translations. Et on peut en faire des personnels…

Hors ligne

#25 27-04-2015 16:24:00

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : [resolu] nettoyage de caractéres éè-,:' et autres sur une arbo

Finalement, j'ai fait une version en perl qui fonctionne. En plus de perl, il faudra installer le
paquet libtext-unaccent-perl. Même usage, que les scripts précédents. Il faut l'utiliser
avec :


find -depth -print0 |xargs -0 special-rename.pl
 


par exemple. Le « -depth » est très important.
Donc voici le script perl :


#! /usr/bin/perl
# -*-coding: UTF-8;-*-

use Text::Unaccent; # in libtext-unaccent-perl
use File::Basename;

sub usage(){
    die("Usage: $0 file [files…]\n");
}

@ARGV || usage;

for (@ARGV) {
    $old_name=$_;
    ($_,$d,$ext)=fileparse($_);
    $_.=$ext;
    $_=unac_string('UTF-8', $_);
    s/\s+/_/g;
    s/-+/_/g;
    s/['"?*:,;!]//g;
    s/[()]+/_/g;
    s/_{2,}/_/g;

    $new_name=$d.$_;

    if (! -e $new_name and $_ ne '' and $new_name ne $old_name) {
        #print "$old_name -> $new_name\n";
        rename($old_name, $new_name) || warn("$!");
    } else {
        warn("Pas de renomage de : $old_name -> $new_name : le fichier existe déjà\n");
    }
}
 

Hors ligne

Pied de page des forums