Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 31/03/2025, à 17:38

BrunoL

[Résolu] Rename -n ... ou pas

Bonjour,

Je viens de récupérer des fichiers aux noms vraiment pourris. Pour commencer je voudrais remplacer les espace dans les noms par des _. Tout semble bien se passer en simulation :

find ${RepPb} -type f | while read i
    do
        echo '--> '"$i"
        rename -n -e "s/\ +/_/g" "$i"
        echo '    '$(echo "$i" | sed "s/\ \+/_/g")
    done

     

$ find ${RepPb} -type f | while read i
    do
        echo '--> '"$i"
        rename -n -e "s/\ +/_/g" "$i"
        echo '    '$(echo "$i" | sed "s/\ \+/_/g")
    done

--> /home/bruno/Temp/Rep 1 root/rep 1 1 A/rep 1 1 2 1/fic 1 1 2 1 - 1
rename(/home/bruno/Temp/Rep 1 root/rep 1 1 A/rep 1 1 2 1/fic 1 1 2 1 - 1, /home/bruno/Temp/Rep_1_root/rep_1_1_A/rep_1_1_2_1/fic_1_1_2_1_-_1)
    /home/bruno/Temp/Rep_1_root/rep_1_1_A/rep_1_1_2_1/fic_1_1_2_1_-_1
--> /home/bruno/Temp/Rep 1 root/rep 1 1 A/rep 1 1 2 1/fic 1 1 2 1 - 2
rename(/home/bruno/Temp/Rep 1 root/rep 1 1 A/rep 1 1 2 1/fic 1 1 2 1 - 2, /home/bruno/Temp/Rep_1_root/rep_1_1_A/rep_1_1_2_1/fic_1_1_2_1_-_2)
    /home/bruno/Temp/Rep_1_root/rep_1_1_A/rep_1_1_2_1/fic_1_1_2_1_-_2
--> /home/bruno/Temp/Rep 1 root/rep 1 1 A/rep 1 1 2 1/fic 1 1 2 1 - 3
rename(/home/bruno/Temp/Rep 1 root/rep 1 1 A/rep 1 1 2 1/fic 1 1 2 1 - 3, /home/bruno/Temp/Rep_1_root/rep_1_1_A/rep_1_1_2_1/fic_1_1_2_1_-_3)
    /home/bruno/Temp/Rep_1_root/rep_1_1_A/rep_1_1_2_1/fic_1_1_2_1_-_3
--> /home/bruno/Temp/Rep 1 root/rep 1 1 B/rep 1 1 2 1/fic 1 1 2 1 - 1
rename(/home/bruno/Temp/Rep 1 root/rep 1 1 B/rep 1 1 2 1/fic 1 1 2 1 - 1, /home/bruno/Temp/Rep_1_root/rep_1_1_B/rep_1_1_2_1/fic_1_1_2_1_-_1)
    /home/bruno/Temp/Rep_1_root/rep_1_1_B/rep_1_1_2_1/fic_1_1_2_1_-_1
--> /home/bruno/Temp/Rep 1 root/rep 1 1 B/rep 1 1 2 1/fic 1 1 2 1 - 2
rename(/home/bruno/Temp/Rep 1 root/rep 1 1 B/rep 1 1 2 1/fic 1 1 2 1 - 2, /home/bruno/Temp/Rep_1_root/rep_1_1_B/rep_1_1_2_1/fic_1_1_2_1_-_2)
    /home/bruno/Temp/Rep_1_root/rep_1_1_B/rep_1_1_2_1/fic_1_1_2_1_-_2
--> /home/bruno/Temp/Rep 1 root/rep 1 1 B/rep 1 1 2 1/fic 1 1 2 1 - 3
rename(/home/bruno/Temp/Rep 1 root/rep 1 1 B/rep 1 1 2 1/fic 1 1 2 1 - 3, /home/bruno/Temp/Rep_1_root/rep_1_1_B/rep_1_1_2_1/fic_1_1_2_1_-_3)
    /home/bruno/Temp/Rep_1_root/rep_1_1_B/rep_1_1_2_1/fic_1_1_2_1_-_3

Je me lance donc avec

$ find ${RepPb} -type f | while read i
    do
        rename -e "s/\ +/_/g" "$i"
    done
Can't rename /home/bruno/Temp/Rep 1 root/rep 1 1 A/rep 1 1 2 1/fic 1 1 2 1 - 1 /home/bruno/Temp/Rep_1_root/rep_1_1_A/rep_1_1_2_1/fic_1_1_2_1_-_1: No such file or directory
Can't rename /home/bruno/Temp/Rep 1 root/rep 1 1 A/rep 1 1 2 1/fic 1 1 2 1 - 2 /home/bruno/Temp/Rep_1_root/rep_1_1_A/rep_1_1_2_1/fic_1_1_2_1_-_2: No such file or directory
Can't rename /home/bruno/Temp/Rep 1 root/rep 1 1 A/rep 1 1 2 1/fic 1 1 2 1 - 3 /home/bruno/Temp/Rep_1_root/rep_1_1_A/rep_1_1_2_1/fic_1_1_2_1_-_3: No such file or directory
Can't rename /home/bruno/Temp/Rep 1 root/rep 1 1 B/rep 1 1 2 1/fic 1 1 2 1 - 1 /home/bruno/Temp/Rep_1_root/rep_1_1_B/rep_1_1_2_1/fic_1_1_2_1_-_1: No such file or directory
Can't rename /home/bruno/Temp/Rep 1 root/rep 1 1 B/rep 1 1 2 1/fic 1 1 2 1 - 2 /home/bruno/Temp/Rep_1_root/rep_1_1_B/rep_1_1_2_1/fic_1_1_2_1_-_2: No such file or directory
Can't rename /home/bruno/Temp/Rep 1 root/rep 1 1 B/rep 1 1 2 1/fic 1 1 2 1 - 3 /home/bruno/Temp/Rep_1_root/rep_1_1_B/rep_1_1_2_1/fic_1_1_2_1_-_3: No such file or directory

J'ai beau tourner le pb dans tous les sens il résiste !
L'arborescence de test :

/home/bruno/Temp/
├── Rep 1 root
│   ├── rep 1 1 A
│   │   └── rep 1 1 2 1
│   │       ├── fic 1 1 2 1 - 1
│   │       ├── fic 1 1 2 1 - 2
│   │       └── fic 1 1 2 1 - 3
│   └── rep 1 1 B
│       └── rep 1 1 2 1
│           ├── fic 1 1 2 1 - 1
│           ├── fic 1 1 2 1 - 2
│           └── fic 1 1 2 1 - 3

Dernière modification par BrunoL (Hier à 16:35)

Hors ligne

#2 Le 31/03/2025, à 18:10

iznobe

Re : [Résolu] Rename -n ... ou pas

Bonjour , normal , vu :

rename(/home/bruno/Temp/Rep 1 root/rep 1 1 A/rep 1 1 2 1/fic 1 1 2 1 - 1, /home/bruno/Temp/Rep_1_root/rep_1_1_A/rep_1_1_2_1/fic_1_1_2_1_-_1)

il ne peut pas faire le renommage , à la fois des dossiers parents , des sous dossiers , et du fichier ...
il faut " remonter " par cran , tu renommes le fichier , puis le dossier parent puis le dossier parent etc ... jusqu ' a arriver à la racine .

Si tu veux tu peux utiliser ce script :

# $i = nom complet rep ou fichier original
# $i1 = chemin relatif du repertoire original
# $j = nom complet rep ou fichier modifié
# $j1 = chemin relatif du repertoire modifié
# $j2 = nom dernier argument modifié

# temps exactement identique pour l' ecriture : if test -e "$i" ou  [[ -e "$i"]]


shopt -s globstar
modif_activ=true;

###Liste des fichiers exclus
Exclus=(CON PRN aux NUL COM1 COM2 COM3 COM4 COM5 COM6 COM7 COM8 COM9 LPT1 LPT2 LPT3 LPT4 LPT5 LPT6 LPT7 LPT8 LPT9)

Long=0; Nbrep=0; Nbfilemodified=0; Nbrepmodified=0; NbfileNOTmodified=0; Debut=$(echo $(date +%s));
echo "liste des fichiers n ' ayant pas pu etre modifiés :" > /tmp/nomodifs
echo "-------------------" > /tmp/modifs

for i in **/*; do
    Nbrep=$(($Nbrep+1))
    # traitement des espaces    
    j=$( echo $i | sed 's@ */ *@/@g' )

    # remplacement d'un maxima de caractères interdits par windows ><\:"|?*
    j=$( echo "$j"  | tr '><"|?*:\\' '!!!!!!!%' ) # echappement de "\" par le meme signe donc 2 \\ pour qu un soit remplacé 

    # Vérifions si le nom n'est pas interdit. Récupération du dernier argument
    j2=$( echo "$j" | grep -o '[^/]*$' )
    if [[ " ${Exclus[*]} " ==  *" $j2 "*  ]]; then j+=_ ; fi

    # Vérifions si la longueur n'est pas excessive
    if [[ "${#j2}" -ge   248 || "${#j}"  -ge 32384 ]] ; then
        if [[ "$long" -eq 0 ]]; then echo "[url]https://www.pcastuces.com/pratique/astuces[/url]" > /tmp/LongFic ; fi
        Long=$(($Long+1))
        echo "$Long : $j" >> /tmp/LongFic
    fi

    if [[ "$i" != "$j" ]]; then # si il y a un changement a effectuer
    
        if test -d "$i" ; then # si c' est un dossier
            if test -e "$j" ; then # on verifie si il existe un dossier du meme nom avant de renommer
                # si deja un dossier du meme nom , on stocke l' erreur
                NbfileNOTmodified=$(($NbfileNOTmodified+1))
                echo "$Nbrep un dossier du meme nom existe deja :'$j' impossible de renommer '$i'" >> /tmp/nomodifs
            else # si pas de dossier du meme nom , on renomme
            echo "on va renommer le répertoire '$i' avec la commande suivante : mkdir '$j'"
                if [ "$modif_activ" = true ] ; then
                    mkdir "$j"
                    if test -e "$j" ; then # si la creation du repertoire a reussi
                        # enregistrement des changements
                        echo "$Nbrep CREERREP : mkdir '$j'" >> /tmp/modifs
                        Nbrepmodified=$(($Nbrepmodified+1))                        
                    else
                        NbfileNOTmodified=$(($NbfileNOTmodified+1))
                        echo "$Nbrep erreur inconnue pour repertoire : '$i'" >> /tmp/nomodifs
                    fi
                fi
            fi
        elif test -f "$i" ; then # si c est un fichier
            # on verifie si il existe un fichier du meme nom avant de renommer
            if test -e "$j" ; then # si deja un fichier du meme nom , on stocke l' erreur
                NbfileNOTmodified=$(($NbfileNOTmodified+1))
                echo "$Nbrep un fichier du meme nom existe deja :\'$j\' impossible de renommer \'$i\'" >> /tmp/nomodifs
            else # si pas de fichier du meme nom , on renomme
                # chemin relatif du repertoire original
                i1=$(echo "$i" | rev | cut -d/  --complement -s -f1 | rev)
                # Récupérons le chemin apres modif 
                j1=$(echo "$j" | rev | cut -d/  --complement -s -f1 | rev) # donne le chemin relatif du repertoire modifié .
                if [[ "$i1" != "$j1" ]]; then # si les chemins sont differents , c' est que l' arborescence a été modifiée :
                    # dans ce cas on utilise l' arborescence modifiée precedemment + le nom modifié du dernier argument pour la destination
                    j=$(echo "$j1/$j2") 
                fi
                echo "on va renommer ce fichier avec la commande suivante : mv '$i' => '$j'"
                if [ "$modif_activ" = true ] ; then
                    mv "$i" "$j"
                    # puis on verifie que le fichier renommé existe bien :
                    if test -e "$j" ; then # si le fichier existe on incremente
                        # enregistrement des changements
                        echo "$Nbrep RENOM : mv '$i' en : '$j'" >> /tmp/modifs
                        Nbfilemodified=$(($Nbfilemodified+1))
                    else # sinon => erreur
                        NbfileNOTmodified=$(($NbfileNOTmodified+1))
                        echo "$Nbrep erreur inconnue pour fichier : '$i'" >> /tmp/nomodifs
                    fi
                fi
            fi
        else # sinon => erreur
            NbfileNOTmodified=$(($NbfileNOTmodified+1))
            echo "$Nbrep erreur inconnue pour : '$i'" >> /tmp/nomodifs
        fi
    fi

done

echo ""
echo "$Nbrep répertoires et fichiers traités, $Nbrepmodified répertoires modifiés, $Nbfilemodified fichiers modifiés, $NbfileNOTmodified répertoires et fichiers n ' ayant pas pu etre modifiés en $(($(date +%s)-$Debut)) secondes."
echo ""
echo "liste des fichiers modifiés ou pas dans '/tmp/modifs' et '/tmp/nomodifs'"
echo ""
if [[ "$Long" > 0 ]]; then echo "vous avez $Long répertoires de taille importante. Voir le détail dans /tmp/LongFic" ; fi

echo "pour supprimer les dossiers vides , copiez collez la commande suivante : find -type d -empty -delete"

ou t ' en inspirer seulement .

tu changes :

modif_activ=true;

par

modif_activ=false;

tu enregistres tu lances le script et tu peux alors voir les modifications qui seraient faites en repassant modif_active à true .

Dernière modification par iznobe (Le 31/03/2025, à 18:19)

Hors ligne

#3 Le 31/03/2025, à 18:27

BrunoL

Re : [Résolu] Rename -n ... ou pas

@iznobe effectivement dit comme cela c'est logique. Mais la fonctionnalité du -n est particulièrement trompeuse.

Je regarde ton script avec attention car comme dit précédemment les noms que j'ai récupéré, sont hallucinants, y-a de tout ... en plus d'un recodage qui a replacé des caractère non utf8 par le caractère <?> utf8. Un festival !
Merci beaucoup.

Hors ligne

#4 Le 31/03/2025, à 19:04

iznobe

Re : [Résolu] Rename -n ... ou pas

le truc , c' est que tu prends une ligne , donc un chemin complet dans ta boucle .
il faudrait ne sortir que les noms de fichiers dans tes lignes .
Mais comme on ne voit pas ce qu ' est : " ${RepPb} " , difficile de modifier big_smile

Hors ligne

#5 Le 31/03/2025, à 21:30

Watael

Re : [Résolu] Rename -n ... ou pas

find "$RepPb" -type f -print0 | while IFS='' read -d '' i

!!!
ça, c'est pour te prémunir contre les alinéas dans les noms de fichiers.

ensuite, puisque tu veux ne renommer que les fichiers :

find "$RepPb" -type f -print0 | while read -d '' line; do fname=${line##*/}; dname=${line%/*}; printf 'mv "%s" "%s"\n' "$line" "$dname/${fname// /_}"; done

Dernière modification par Watael (Hier à 17:38)


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#6 Hier à 13:23

BrunoL

Re : [Résolu] Rename -n ... ou pas

@iznobe j'ai un petit problème dans la compréhension de ton script. Que fait :

                # chemin relatif du repertoire original
                i1=$(echo "$i" | rev | cut -d/  --complement -s -f1 | rev)

Sur des chemins contenant du codage="8859_1" la commande bloque.

Dernière modification par BrunoL (Hier à 13:26)

Hors ligne

#7 Hier à 15:16

BrunoL

Re : [Résolu] Rename -n ... ou pas

@iznobe OK je me réponds après modification. La commande fige (très désagréable pour le débbug de for et if imbriqués ;-)
Cette commande ne digère pas les caractères exotique. Bon c'est réglé je continue.
Très bien ton script, j'apprécie particulièrement la simulation avant traitement.
Encore merci.

Dernière modification par BrunoL (Hier à 15:16)

Hors ligne

#8 Hier à 16:33

BrunoL

Re : [Résolu] Rename -n ... ou pas

Terminé !
Les datas sont propres. Encore merci iznobe ça aurait été beaucoup plus long sans ton aide.

Pour amener ma petite pierre à l'édifice, en cas de traitement sur fichier avec encodage foireux éviter  :

                # chemin relatif du repertoire original
                i1=$(echo "$i" | rev | cut -d/  --complement -s -f1 | rev)

Je suggère (sans prétention) de préférer :

                # chemin relatif du repertoire original
                ##i1=$(echo "$i" | rev | cut -d/  --complement -s -f1 | rev)
                lgC=${#i}
                chaiF=$(basename $i)
                lgF=${#chaiF}
                i1=${i:0:$((lgC - lgF))}

Petit complément, chez moi convmv ne donnait pas des résultats corrects j'ai du employer iconv.
Bonne fin de journée.

Hors ligne

#9 Hier à 17:33

Watael

Re : [Résolu] Rename -n ... ou pas

nomFic=${i##*/}
nomRep=${i%/*}

roll

Dernière modification par Watael (Hier à 17:36)


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#10 Hier à 17:41

iznobe

Re : [Résolu] Rename -n ... ou pas

Salut et merci pour la modif en cas d' encodage " foireux " .

Par contre , pas bien compris ton " petit complément " .
Aprés ca fait longtemps que j' ai pas remis le nez dans ce script .

sinon j' ai essayé la modif que tu as donnée mais ca n ' a pas l' aire de fonctionner car j' obtiens des :

basename: opérande supplémentaire «xxx/xxxv»
Saisissez « basename --help » pour plus d'informations.

Dernière modification par iznobe (Hier à 18:28)

Hors ligne

#11 Hier à 18:48

BrunoL

Re : [Résolu] Rename -n ... ou pas

Curieux, le copier/coller vient du source exécuté !?
Après vérification, je confirme que les lignes ajoutées sont celles appliquées lors du traitement de mes répertoires.
Par complément j'évoquais la "création" d'un journal de simulation pour vérifier les mises à jour prévues. Mais chose intéressante avec ces pb de codage, le journal en question n'est "exploitable" qu'avec un cat car l'usage d'un éditeur (type geany) ajoute sa couche de pb de recodage. Marrant mais je n'ai pas approfondi ces pb m’intéressent peu wink
Je garde la solution de Watael pour la prochaine fois smile

Edit : je ne sais plus pour régler quel problème mais j'ai dû ajouter en début de script

export LANG=C.UTF-8

Cela peut expliquer ...

Dernière modification par BrunoL (Hier à 18:50)

Hors ligne

#12 Hier à 19:48

iznobe

Re : [Résolu] Rename -n ... ou pas

En fait , je me suis un peu re penché sur le script et j' ai modifié 2 bricoles , surtout pour la présentation des modifs et j ' ai inclus une variable pour designer un repertoire specifique plutot que de deplacer le script dans le rdossier courant .
Mais ça fonctionne aussi dans le dossier courant si on veut .

Pour l' erreur , il suffisait d' ajouter des quotes ( " ) pour encadrer la variable : $i pour ne plus avoir l' erreur .

j ' ai donc implémenté le code de @Watael , simplifier 2 bricoles et enlever quelques commentaires superflus .

-------------------------------------

Watael a écrit :
nomFic=${i##*/}
nomRep=${i%/*}

roll

et c' est maintenant que tu me sors ça hmm
tongue tongue

Bref voici le nouveau script : https://forum.ubuntu-fr.org/viewtopic.p … #p22832319

Peut être qu ' on pourrait demander à déplacer ce script dans trucs et astuces utiles d' ailleurs non ?

Dernière modification par iznobe (Hier à 19:58)

Hors ligne