#101 Le 19/04/2026, à 22:23
- Watael

Re : [RESOLU] script mettre en conformité les noms de fichiers samba
que s'est-il passé avec COM et LPT ? pourquoi sont-ils "indicés" ?
Connected \o/
Welcome to sHell. · eval is evil.
En ligne
#102 Le 20/04/2026, à 05:38
- iznobe

Re : [RESOLU] script mettre en conformité les noms de fichiers samba
Bonjour : https://learn.microsoft.com/fr-fr/windo … ing-a-file
N’utilisez pas les noms réservés suivants comme nom d’un fichier :
CON, PRN, AUX, NUL, COM0, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, COM¹, COM², COM³, LPT0, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9, LPT¹, LPT², et LPT³. Évitez également ces noms suivis immédiatement d’une extension ; par exemple, NUL.txt et NUL.tar.gz sont tous deux équivalents à NUL. Pour plus d’informations, consultez l’article Espaces de noms.
j ' ai retravaillé et " optimisé " le script :
#!/bin/bash
# Description des variables :
# $nomOriginal = nom complet rep ou fichier original
# $pathOriginal = chemin du repertoire original
# $nomModif = nom complet rep ou fichier modifié
# $pathModif = chemin du repertoire modifié
# $nomArgModif = nom dernier argument modifié
# FPNWE = chemin du fichier complet sans .ext = Full Path Name Without Extension
# $ext = extension du fichier le cas échéant sinon , renvoie le chemin complet du fichier.
# $fileNameWE = nom du fichier sans path , ni extension .
# --- Configuration ---
modif_activ=false # true pour appliquer les modifications
all_spaces=false # true pour remplacer tous les espaces
execDir="" # Chemin ABSOLU du dossier cible (vide = PWD)
#### FIN ####
# --- Variables globales ---
declare -i LongPath=0 NbNOTScanned=0 NbRepScanned=0 NbFileScanned=0 NbRepModified=0 NbFileModified=0 NbRepNOTModified=0 NbFileNOTModified=0; Debut=$(date +%s);
declare log_error="/tmp/error.log" log_modifs="/tmp/modifs"
### Liste des fichiers exclus
Exclus=( CON PRN AUX NUL NULL COM{0..9} LPT{0..9} COM¹ COM² COM³ LPT¹ LPT² LPT³ CLOCK$ )
# --- Initialisation ---
shopt -s globstar nullglob
echo "liste des erreurs ( fichiers ou dossiers ) n ' ayant pas pu etre modifiés :" > "$log_error"
echo "-------------------" > "$log_modifs"
# --- Fonctions ---
clean_complete_name() { # Nettoie un nom de fichier/dossier
local name="$1"
# Nettoyage des espaces (début, fin, autour des /, multiples)
name=$(printf '%s' "$name" | sed -E '
s/^[[:space:]]+//;
s/[[:space:]]+$//;
s/[[:space:]]*\/[[:space:]]*/\//g;
s/[[:space:]]+/ /g
')
# Remplacement des caractères interdits
if test "$all_spaces" = true; then
name=$(printf '%s' "$name" | tr '><"|?*\\ :' '_________')
else
name=$(printf '%s' "$name" | tr '><"|?*\\:' '________')
fi
printf '%s\n' "$name"
}
for nomOriginal in "${execDir:=$PWD}"/**/*; do
if test -L "$nomOriginal"; then
((NbNOTScanned++))
continue
elif test -f "$nomOriginal"; then
((NbFileScanned++))
ext=${nomOriginal##*.} # get extension without filename
if test "$nomOriginal" != "$ext"; then # si le fichier comporte une extension
FPNWE="${nomOriginal%.*}" # get filename without extension
FPNWE=$(clean_complete_name "$FPNWE")
fileNameWE=${FPNWE##*/} # get only filename
if [[ "${Exclus[*]}" == *" $fileNameWE "* ]]; then FPNWE+="_"; fi
ext=$(clean_complete_name "$ext")
nomModif="$FPNWE.$ext"
else
nomModif=$(clean_complete_name "$nomOriginal")
nomArgModif=$(echo "$nomModif" | grep -o '[^/]*$') # Récupére le dernier argument
if [[ "${Exclus[*]}" == *" $nomArgModif "* ]]; then nomModif+="_"; fi # Vérifions si le nom n'est pas interdit.
fi
else
((NbRepScanned++))
nomModif=$(clean_complete_name "$nomOriginal")
fi
if [[ "$nomOriginal" != "$nomModif" ]]; then # si il y a un changement a effectuer
nomArgModif=$(echo "$nomModif" | grep -o '[^/]*$') # Récupére le dernier argument
# le nom du chemin ne doit pas dépasser 256 en standard , et chemin étendu 32767 max , prefixe windows = "\\?\" .
#if (( "${#nomArgModif}" >= 256 || "${#nomModif}" >= 32767 )) ; then # Vérifions si la longueur n'est pas excessive
if (( "${#nomModif}" >= 256 )) ; then # Vérifions si la longueur n'est pas excessive
((LongPath++))
echo "Le nom de chemin de fichier est trop long ! impossible de renommer '$nomOriginal' en '$nomModif'" >> "$log_error"
fi
if test -d "$nomOriginal"; then # si c' est un dossier
if test -e "$nomModif"; then # on verifie si il existe un dossier du meme nom avant de renommer et si il est modifiable
((NbRepNOTModified++))
echo "$NbRepNOTModified un dossier du meme nom existe deja : impossible de renommer '$nomOriginal' en '$nomModif'" >> "$log_error"
elif test ! -w "$nomOriginal"; then
((NbRepNOTModified++))
echo "$NbRepNOTModified permission refusée : impossible de renommer '$nomOriginal' en '$nomModif'" >> "$log_error"
else # si pas de dossier du meme nom , on renomme
if test "$modif_activ" = true; then
mkdir -p "$nomModif"
echo "on renomme le dossier : mkdir '$nomOriginal' ==> '$nomModif'"
((NbRepModified++))
echo "$NbRepModified CREER_REP : mkdir '$nomModif'" >> "$log_modifs"
fi
fi
elif test -f "$nomOriginal" ; then # si c est un fichier
if test -e "$nomModif"; then # on verifie si il existe un fichier du meme nom avant de renommer et s ' il est modifiable
((NbFileNOTModified++))
echo "$NbFileNOTModified un fichier du meme nom existe deja : impossible de renommer '$nomOriginal' en '$nomModif'" >> "$log_error"
elif test ! -w "$nomOriginal"; then
((NbFileNOTModified++))
echo "$NbFileNOTModified : permission refusée : impossible de renommer '$nomOriginal' en '$nomModif'" >> "$log_error"
else # si pas de fichier du meme nom , on renomme
pathOriginal=${nomOriginal%/*} # chemin du repertoire original
pathModif=${nomModif%/*} # chemin apres modif
if [[ "$pathOriginal" != "$pathModif" ]]; then # si les chemins sont differents , c' est que l' arborescence a été modifiée :
nomModif="$pathModif"/"$nomArgModif" # dans ce cas on utilise l' arborescence modifiée precedemment + le nom modifié du dernier argument pour la destination
fi
echo "renommage du fichier : mv '$nomOriginal' ==> '$nomModif'"
if test "$modif_activ" = true; then
mv "$nomOriginal" "$nomModif"
NbFileModified+=1
echo "$NbFileModified RENOM : mv '$nomOriginal' en : '$nomModif'" >> "$log_modifs"
fi
fi
fi
fi
done
# --- Affichage récapitulatif ---
echo "$NbRepScanned dossiers et $NbFileScanned fichiers traités, $NbRepModified répertoires modifiés, $NbFileModified fichiers modifiés , le tout en $(($(date +%s)-Debut)) secondes."
(( NbNOTScanned )) && echo "$NbNOTScanned non traités."
echo;
(( NbFileModified || NbRepModified )) && echo "liste des dossiers et fichiers modifiés dans '/tmp/modifs'"
(( NbRepModified )) && echo "pour supprimer les dossiers vides , copiez collez la commande suivante : find '${execDir:=$PWD}' -type d -empty -delete"
echo;
if (( NbFileNOTModified || NbRepNOTModified || LongPath)); then
echo "$NbFileNOTModified fichiers , $NbRepNOTModified répertoires n ' ayant pas pu etre modifiés"
echo "vous avez $LongPath répertoires de taille trop importante."
echo "liste des erreurs : cat '$log_error'"
echo;
fiMais plus je décompose , plus il est lent ...
En tout cas , là l ' algo fonctionne parfaitement bien me semble t il :
iznobe@iznobe-PC-U2604:~/Scripts/test$ ls -l
total 28
-rw-r----- 1 iznobe iznobe 0 Apr 17 00:29 ' test : .ino '
-rw-r----- 1 iznobe iznobe 15 Apr 17 00:29 ' bash.sh '
-rw-rw-r-- 1 iznobe iznobe 6 Apr 17 00:29 '><"|?*\ :'
drwxrwxr-x 2 iznobe iznobe 4096 Apr 18 10:22 COM
-rw-rw-r-- 1 iznobe iznobe 5 Apr 18 10:37 COM0
drwxrwxr-x 2 iznobe iznobe 4096 Apr 18 10:24 COM5
-rw-r----- 1 iznobe iznobe 0 Apr 17 00:29 COM6
drwxrwxr-x 2 iznobe iznobe 4096 Apr 18 09:55 LPT
-rw-rw-r-- 1 iznobe iznobe 5 Apr 18 11:31 LPT0.sh
lrwxrwxrwx 1 iznobe iznobe 30 Apr 18 09:43 rename.sh -> /home/iznobe/Scripts/rename.sh
iznobe@iznobe-PC-U2604:~/Scripts/test$ bash ~/Scripts/rename.sh
renommage du fichier : mv '/home/iznobe/Scripts/test/><"|?*\ :' ==> '/home/iznobe/Scripts/test/_______ _'
renommage du fichier : mv '/home/iznobe/Scripts/test/ bash.sh ' ==> '/home/iznobe/Scripts/test/bash.sh'
renommage du fichier : mv '/home/iznobe/Scripts/test/COM0' ==> '/home/iznobe/Scripts/test/COM0_'
renommage du fichier : mv '/home/iznobe/Scripts/test/COM6' ==> '/home/iznobe/Scripts/test/COM6_'
renommage du fichier : mv '/home/iznobe/Scripts/test/LPT0.sh' ==> '/home/iznobe/Scripts/test/LPT0_.sh'
renommage du fichier : mv '/home/iznobe/Scripts/test/ test : .ino ' ==> '/home/iznobe/Scripts/test/test _.ino'
3 dossiers et 6 fichiers traités, 0 répertoires modifiés, 0 fichiers modifiés , le tout en 0 secondes.
1 non traités.
iznobe@iznobe-PC-U2604:~/Scripts/test$ Dernière modification par iznobe (Le 20/04/2026, à 08:26)
Hors ligne
#103 Le 21/04/2026, à 21:13
- iznobe

Re : [RESOLU] script mettre en conformité les noms de fichiers samba
La même chose , en mieux , plus complet et plus rapide :
#!/bin/bash
sanitize() {
shopt -s extglob;
filename=$(basename "$1")
directory=$(dirname "$1")
name_clean=$(sed -E \
-e 's/^[[:space:]]*//' \
-e 's/[[:space:]]*$//' \
-e 's/[[:space:]]*\/[[:space:]]*/\//g' \
-e 's/[[:space:]]+/ /g' \
-e 's/[\\/:\*\?\"<>\|\x01-\x1F\x7F]/_/g' \
-e "s/'/_/g" \
-e 's/\.+$//' \
-e 's/[[:space:]]*\.[[:space:]]*([^.]+)$/.\1/' \
-e 's/^\.*$//' \
-e 's/^(nul|prn|con|lpt[0-9]|com[0-9]|aux|COM¹|COM²|COM³|LPT¹|LPT²|LPT³)(\.|$)/\1_\2/I' \
-e 's/^[[:space:]]*$/NONAME/' <<< "$filename")
# 1 Suppression des espaces en début de ligne
# 2 Suppression des espaces en fin de ligne
# 3 Remplace toute séquence d’espaces autour d’une barre oblique (/) par une seule barre oblique
# 4 Remplacement des espaces multiples par un seul espace
# 5 Remplacement des caractères interdits par des underscores
# 6 Remplacement des apostrophes par des underscores
# 7 Suppression des points en fin de nom
# 8 Suppression des espaces juste avant et / ou apres le dernier point
# 9 Suppression des noms ne contenant que des points
# 10 si nom exclu on ajoute le suffixe "_".
# 11 si espace ou vide => NONAME
if [ "$filename" != "$name_clean" ]; then
target="$directory/$name_clean"
suffix=0
final_name="$target"
# eviter les doublons et renommer correctement quand meme :
while [ -e "$final_name" ]; do # Tant que le fichier cible existe déjà
name="${name_clean##*/}" # enlève le chemin
ext=""
if [[ "$name" == .* ]]; then
base="${name:1}" # enlève le point initial
if [[ "$base" == *.* ]]; then
ext="${base##*.}"
fi
else
if [[ "$name" == *.* ]]; then
ext="${name##*.}"
fi
fi
# Permet de renommer le tout , car $ext est deinie a vide au départ
final_name="${directory}/${name}_${suffix}${ext}"
((suffix++))
done
echo " => '$1' serait renommé en '$final_name'"
#mv -v "$1" "$directory/$name_clean"
fi
}
export -f sanitize
sanitize_dir() {
find "$1" -depth -exec bash -c 'sanitize "$0"' {} \;
}
sanitize_dir "$PWD"Dernière modification par iznobe (Le 21/04/2026, à 21:24)
Hors ligne
#104 Le 21/04/2026, à 22:43
- Watael

Re : [RESOLU] script mettre en conformité les noms de fichiers samba
pour le sed tu peux te dispenser de tous ces -e, et avoir seulement quatres apostrophes (au début, à la fin, et deux pour protéger celui de la substitution de l'apostrophe !
).
plus besoin non plus des antislash en fin de lignes.
nameClean=$(sed -E '
s/^[[:space:]]+//
s/[[:space:]]+$//
s/'\''/_/g
#etc' <<<"$filename"tu vois que tu peux aussi insérer des commentaires.
Dernière modification par Watael (Le 21/04/2026, à 22:44)
Connected \o/
Welcome to sHell. · eval is evil.
En ligne
#105 Le 22/04/2026, à 00:34
- iznobe

Re : [RESOLU] script mettre en conformité les noms de fichiers samba
oui , j ' avais vu qu ' on pouvait faire sans les -e , mais pas qu ' on pouvait mettre des com en plus .
Du coup j ' ai modifié car ça me saoulait cette histoire , c ' est bien plus pratique comme ça !
Merci .
j ' ai aussi rectifié le mv commenté ... , et enlevé une variable inutile :
#!/bin/bash
sanitize() {
shopt -s extglob;
filename=$(basename "$1")
directory=$(dirname "$1")
name_clean=$(sed -E '
s/^[[:space:]]*// # Suppression des espaces en début de ligne
s/[[:space:]]*$// # Suppression des espaces en fin de ligne
s/[[:space:]]*\/[[:space:]]*/\//g # Remplace toute séquence d espaces autour d une barre oblique (/) par une seule barre oblique
s/[[:space:]]+/ /g # Remplacement des espaces multiples par un seul espace
s/['\''\\/:\*\?\"<>\|\x01-\x1F\x7F]/_/g # Remplacement des apostrophes et des caractères interdits par des underscores
s/\.+$// # Suppression des points en fin de nom
s/[[:space:]]*\.[[:space:]]*([^.]+)$/.\1/ # Suppression des espaces juste avant et / ou apres le dernier point
s/^\.*$// # Suppression des noms ne contenant que des points
s/^(nul|prn|con|lpt[0-9]|com[0-9]|aux|COM¹|COM²|COM³|LPT¹|LPT²|LPT³)(\.|$)/\1_\2/I # si nom exclu on ajoute le suffixe _
s/^[[:space:]]*$/NONAME/' <<< "$filename") # si espace ou vide => NONAME
if test "$filename" != "$name_clean"; then
suffix=0
final_name="$directory/$name_clean"
# eviter les doublons et renommer correctement quand meme :
while test -e "$final_name"; do # Tant que le fichier cible existe déjà
name="${name_clean##*/}" # enlève le chemin
base="$name"
ext=""
if [[ "$name" == .* ]]; then
base="${name:1}" # enlève le point initial
if [[ "$base" == *.* ]]; then
ext="${base##*.}"
base="${base%.*}"
fi
else
if [[ "$name" == *.* ]]; then
ext="${name##*.}"
base="${name%.*}"
fi
fi
# Permet de renommer le tout ( les 4 possibilités ) , car $ext et $base sont definies au départ
final_name="${directory}/${base}_${suffix}${ext}"
((suffix++))
done
echo " => '$1' serait renommé en '$final_name'"
#mv -v "$1" "$final_name"
fi
}
export -f sanitize
sanitize_dir() {
Debut=$(date +%s);
find "$1" -depth -exec bash -c 'sanitize "$0"' {} \;
echo "le tout en $(($(date +%s)-Debut)) secondes."
}
sanitize_dir "$PWD"Dernière modification par iznobe (Le 22/04/2026, à 11:54)
Hors ligne
#106 Le 22/04/2026, à 12:16
- iznobe

Re : [RESOLU] script mettre en conformité les noms de fichiers samba
j ' ai le meme probleme avec les 2 versions du script :
iznobe@m-pi3:~/test $ bash ~/samba_rename.sh
renommage du fichier : mv '/home/iznobe/test/*' ==> '/home/iznobe/test/_'
renommage du fichier : mv '/home/iznobe/test/><"|?* \\ :' ==> '/home/iznobe/test/______ __ _'
renommage du fichier : mv '/home/iznobe/test/><"|?*\ :' ==> '/home/iznobe/test/_______ _'
renommage du fichier : mv '/home/iznobe/test/COM6' ==> '/home/iznobe/test/COM6_'
renommage du fichier : mv '/home/iznobe/test/oiu* ^poiopjh, $. yu / MAIS !:;,ù$*^ô . FUCK' ==> '/home/iznobe/test/oiu_ ^poiopjh, $. yu/MAIS !_;,ù$_^ô.FUCK'
renommage du fichier : mv '/home/iznobe/test/ @pour , ù? @ ' ==> '/home/iznobe/test/@pour , ù_ @'
renommage du fichier : mv '/home/iznobe/test/ @pour , ù? @ *' ==> '/home/iznobe/test/@pour , ù_ @ _'
renommage du fichier : mv '/home/iznobe/test/ @pour , ù? @ * \\' ==> '/home/iznobe/test/@pour , ù_ @ _ __'
renommage du fichier : mv '/home/iznobe/test/ @pour , ù? @ \\ ' ==> '/home/iznobe/test/@pour , ù_ @ __'
renommage du fichier : mv '/home/iznobe/test/ @pour , ù? @ * \\ jk ' ==> '/home/iznobe/test/@pour , ù_ @ _ __ jk'
renommage du fichier : mv '/home/iznobe/test/ test : . ino ' ==> '/home/iznobe/test/test _.ino'
renommage du fichier : mv '/home/iznobe/test/ test : .ino ' ==> '/home/iznobe/test/test _.ino'renommage du fichier : mv '/home/iznobe/test/ test . test / test . test ' ==> '/home/iznobe/test/test . test/test.test' renommage du fichier : mv '/home/iznobe/test/ test . test / test . test ' ==> '/home/iznobe/test/test . test/test.test'2 dossiers et 20 fichiers traités, 0 répertoires modifiés, 0 fichiers modifiés , le tout en 1 secondes.
1 fichiers , 0 répertoires n ' ayant pas pu etre modifiés
vous avez 0 répertoires de taille trop importante.
liste des erreurs : cat '/tmp/error.log'iznobe@m-pi3:~/test $
et
iznobe@m-pi3:~/test $ bash ~/sanitize.sh
=> '/home/iznobe/test/ @pour , ù? @ * \\' serait renommé en '/home/iznobe/test/@pour , ù_ @ _ __'
=> '/home/iznobe/test/><"|?* \\ :' serait renommé en '/home/iznobe/test/______ __ _'
=> '/home/iznobe/test/ test : . ino ' serait renommé en '/home/iznobe/test/test _.ino'
=> '/home/iznobe/test/ @pour , ù? @ \\ ' serait renommé en '/home/iznobe/test/@pour , ù_ @ __'
=> '/home/iznobe/test/><"|?*\ :' serait renommé en '/home/iznobe/test/_______ _'
=> '/home/iznobe/test/ @pour , ù? @ * \\ jk ' serait renommé en '/home/iznobe/test/@pour , ù_ @ _ __ jk'
=> '/home/iznobe/test/ @pour , ù? @ *' serait renommé en '/home/iznobe/test/@pour , ù_ @ _'
=> '/home/iznobe/test/COM6' serait renommé en '/home/iznobe/test/COM6_'=> '/home/iznobe/test/ test . test / test . test ' serait renommé en '/home/iznobe/test/ test . test /test.test' => '/home/iznobe/test/ test . test / test . test ' serait renommé en '/home/iznobe/test/ test . test /test.test' => '/home/iznobe/test/ test . test ' serait renommé en '/home/iznobe/test/test.test'=> '/home/iznobe/test/ test: fichier de test % ? ' serait renommé en '/home/iznobe/test/test_ fichier de test % __0'
=> '/home/iznobe/test/ @pour , ù? @ ' serait renommé en '/home/iznobe/test/@pour , ù_ @'
=> '/home/iznobe/test/ test : .ino ' serait renommé en '/home/iznobe/test/test _.ino'
=> '/home/iznobe/test/*' serait renommé en '/home/iznobe/test/_'
=> '/home/iznobe/test/oiu* ^poiopjh, $. yu / MAIS !:;,ù$*^ô . FUCK' serait renommé en '/home/iznobe/test/oiu* ^poiopjh, $. yu /MAIS !_;,ù$_^ô.FUCK'
=> '/home/iznobe/test/oiu* ^poiopjh, $. yu ' serait renommé en '/home/iznobe/test/oiu_ ^poiopjh, $.yu'
le tout en 1 secondes.
iznobe@m-pi3:~/test $
je me retrouve au final avec 2 fichiers du meme nom dans un dossier , si je ne dis pas de betises ![]()
Avec un point bonus pour le sanitize : le dossier qui contient les fichiers est correctement renommé .
Dernière modification par iznobe (Le 22/04/2026, à 12:20)
Hors ligne
#107 Le 22/04/2026, à 13:03
- Watael

Re : [RESOLU] script mettre en conformité les noms de fichiers samba
je me retrouve au final avec 2 fichiers du meme nom dans un dossier , si je ne dis pas de betises
ce qui n'est pas possible : le dernier trouvé écrasera le précédent. ![]()
mv a des options pour éviter ça (en ajoutant un suffixe numérique), mais le script pour l'instant ne peut pas le (pré)dire, et mv, que je voie, n'a pas d'option "dry-run".
Connected \o/
Welcome to sHell. · eval is evil.
En ligne
#108 Le 22/04/2026, à 13:27
- iznobe

Re : [RESOLU] script mettre en conformité les noms de fichiers samba
l ' idéal , serait donc de commencer par renommer les dossiers avant les fichiers , puis de vérifier les noms de fichiers , non ?
Autre chose , dans le script samba_rename.h , je ne vois pas de : echo "on renomme le dossier : mkdir '$nomOriginal' ==> '$nomModif'"
Ce qui n' est pas normal , car justement , il est censé renommer d ' abord les dossiers :
if test -d "$nomOriginal"; then # si c' est un dossier
if test -e "$nomModif"; then # on verifie si il existe un dossier du meme nom avant de renommer et si il est modifiable
((NbRepNOTModified++))
echo "$NbRepNOTModified un dossier du meme nom existe deja : impossible de renommer '$nomOriginal' en '$nomModif'" >> "$log_error"
elif test ! -w "$nomOriginal"; then
((NbRepNOTModified++))
echo "$NbRepNOTModified permission refusée : impossible de renommer '$nomOriginal' en '$nomModif'" >> "$log_error"
else # si pas de dossier du meme nom , on renomme
if test "$modif_activ" = true; then
mkdir -p "$nomModif"
echo "on renomme le dossier : mkdir '$nomOriginal' ==> '$nomModif'"
((NbRepModified++))
echo "$NbRepModified CREER_REP : mkdir '$nomModif'" >> "$log_modifs"
fi
fi
elif test -f "$nomOriginal" ; then # si c est un fichier
...EDIT , juste le echo qui était mal placé , il faut le mettre :
else # si pas de dossier du meme nom , on renomme
echo "on renomme le dossier : mkdir '$nomOriginal' ==> '$nomModif'"
if test "$modif_activ" = true; then
mkdir -p "$nomModif"Dernière modification par iznobe (Le 22/04/2026, à 13:55)
Hors ligne
#109 Le 22/04/2026, à 13:42
- Watael

Re : [RESOLU] script mettre en conformité les noms de fichiers samba
l ' idéal , serait donc de commencer par renommer les dossiers avant les fichiers , puis de vérifier les noms de fichiers , non ?
je crois que non.
ce qui est dans le dossier est renommé - si un fichier/dossier existe mv lui ajoutera un suffixe, quel que soit la direction
Dernière modification par Watael (Le 22/04/2026, à 15:48)
Connected \o/
Welcome to sHell. · eval is evil.
En ligne
#110 Le 22/04/2026, à 15:42
- iznobe

Re : [RESOLU] script mettre en conformité les noms de fichiers samba
En fait ça fonctionne bien si le " mv " est activé avec le script sanitize qui lui , gère les doublons .
le echo ne reflète pas tout forcément ![]()
Par contre , ce n' est pas le cas du samba_rename qui ne gere pas les doublons ( et pas correctement les espaces dans les noms de dossiers et autour des '.' .
Dernière modification par iznobe (Le 22/04/2026, à 16:29)
Hors ligne
#111 Le 22/04/2026, à 18:36
- iznobe

Re : [RESOLU] script mettre en conformité les noms de fichiers samba
le script " tout pas beau " samba_rename :
récapitulatif :
383 dossiers et 5374 fichiers traités, 0 répertoires modifiés, 0 fichiers modifiés , le tout en 43 secondes.le sanitize : 88 secondes
![]()
les 2 fonctionnent maintenant .
le script sanitize.sh gère les renommages avec suffixe _X ( ou X est un numéro ) dans le cas ou le fichier existe déjà :
#!/bin/bash
sanitize() {
shopt -s extglob;
filename=$(basename "$1")
directory=$(dirname "$1")
name_clean=$(sed -E '
s/^[[:space:]]*// # Suppression des espaces en début de ligne
s/[[:space:]]*$// # Suppression des espaces en fin de ligne
s/[[:space:]]*\/[[:space:]]*/\//g # Remplace toute séquence d espaces autour d une barre oblique (/) par une seule barre oblique
s/[[:space:]]+/ /g # Remplacement des espaces multiples par un seul espace
s/['\''\\/:\*\?\"<>\|\x01-\x1F\x7F]/_/g # Remplacement des apostrophes et des caractères interdits par des underscores
s/\.+$// # Suppression des points en fin de nom
s/[[:space:]]*\.[[:space:]]*([^.]+)$/.\1/ # Suppression des espaces juste avant et / ou apres le dernier point
s/^\.*$// # Suppression des noms ne contenant que des points
s/^(nul|prn|con|lpt[0-9]|com[0-9]|aux|COM¹|COM²|COM³|LPT¹|LPT²|LPT³)(\.|$)/\1_\2/I # si nom exclu on ajoute le suffixe _
s/^[[:space:]]*$/NONAME/' <<< "$filename") # si espace ou vide => NONAME
if test "$filename" != "$name_clean"; then
suffix=0
final_name="$directory/$name_clean"
# eviter les doublons et renommer correctement quand meme :
while test -e "$final_name"; do # Tant que le fichier cible existe déjà
name="${name_clean##*/}" # enlève le chemin
base="$name"
ext=""
if [[ "$name" == .* ]]; then
base="${name:1}" # enlève le point initial
if [[ "$base" == *.* ]]; then
ext=".${base##*.}"
base="${base%.*}"
fi
else
if [[ "$name" == *.* ]]; then
ext=".${name##*.}"
base="${name%.*}"
fi
fi
# Permet de renommer le tout ( les 4 possibilités ) , car $ext et $base sont definies au départ
final_name="${directory}/${base}_${suffix}${ext}"
((suffix++))
done
echo " => '$1' serait renommé en '$final_name'"
mv -v "$1" "$final_name"
fi
}
export -f sanitize
sanitize_dir() {
Debut=$(date +%s);
find "$1" -depth -exec bash -c 'sanitize "$0"' {} \;
echo "le tout en $(($(date +%s)-Debut)) secondes."
}
sanitize_dir "$PWD"le script samba rename , indique qu ' il n ' a pas pu renommer , mais il est 2 fois plus rapide :
#!/bin/bash
# Description des variables :
# $nomOriginal = nom complet rep ou fichier original
# $pathOriginal = chemin du repertoire original
# $nomModif = nom complet rep ou fichier modifié
# $pathModif = chemin du repertoire modifié
# $nomArgModif = nom dernier argument modifié
# FPNWE = chemin du fichier complet sans .ext = Full Path Name Without Extension
# $ext = extension du fichier le cas échéant sinon , renvoie le chemin complet du fichier.
# $fileNameWE = nom du fichier sans path , ni extension .
# --- Configuration ---
modif_activ=false # true pour appliquer les modifications
execDir="" # Chemin ABSOLU du dossier cible (vide = PWD)
#### FIN ####
# --- Variables globales ---
declare -i LongPath=0 NbNOTScanned=0 NbRepScanned=0 NbFileScanned=0 NbRepModified=0 NbFileModified=0 NbRepNOTModified=0 NbFileNOTModified=0; Debut=$(date +%s);
declare log_error="/tmp/error.log" log_modifs="/tmp/modifs"
### Liste des fichiers exclus
Exclus=( CON PRN AUX NUL NULL COM{0..9} LPT{0..9} COM¹ COM² COM³ LPT¹ LPT² LPT³ CLOCK$ )
# --- Initialisation ---
shopt -s globstar nullglob
echo "liste des erreurs ( fichiers ou dossiers ) n ' ayant pas pu etre modifiés :" > "$log_error"
echo "-------------------" > "$log_modifs"
# --- Fonctions ---
clean_complete_name() { # Nettoie un nom de fichier/dossier
local name="$1"
# Nettoyage des espaces (début, fin, autour des /, multiples)
name=$(printf '%s' "$name" | sed -E '
s/^[[:space:]]+//;
s/[[:space:]]+$//;
s/[[:space:]]*\/[[:space:]]*/\//g;
s/[[:space:]]+/ /g
s/[[:space:]]*\.[[:space:]]*([^.]+)$/.\1/ # Suppression des espaces juste avant et / ou apres le dernier point
'| tr ''\''><"|?*\\:' '_________')
printf '%s\n' "$name"
}
for nomOriginal in "${execDir:=$PWD}"/**/*; do
if test -L "$nomOriginal"; then
((NbNOTScanned++))
continue
elif test -f "$nomOriginal"; then
((NbFileScanned++))
ext=${nomOriginal##*.} # get extension without filename
if test "$nomOriginal" != "$ext"; then # si le fichier comporte une extension
FPNWE="${nomOriginal%.*}" # get filename without extension
FPNWE=$(clean_complete_name "$FPNWE")
fileNameWE=${FPNWE##*/} # get only filename
if [[ "${Exclus[*]}" == *" $fileNameWE "* ]]; then FPNWE+="_"; fi
ext=$(clean_complete_name "$ext")
nomModif="$FPNWE.$ext"
else
nomModif=$(clean_complete_name "$nomOriginal")
nomArgModif=$(echo "$nomModif" | grep -o '[^/]*$') # Récupére le dernier argument
if [[ "${Exclus[*]}" == *" $nomArgModif "* ]]; then nomModif+="_"; fi # Vérifions si le nom n'est pas interdit.
fi
else
((NbRepScanned++))
nomModif=$(clean_complete_name "$nomOriginal")
fi
if [[ "$nomOriginal" != "$nomModif" ]]; then # si il y a un changement a effectuer
nomArgModif=$(echo "$nomModif" | grep -o '[^/]*$') # Récupére le dernier argument
# le nom du chemin ne doit pas dépasser 256 en standard , et chemin étendu 32767 max , prefixe windows = "\\?\" .
#if (( "${#nomArgModif}" >= 256 || "${#nomModif}" >= 32767 )) ; then # Vérifions si la longueur n'est pas excessive
if (( "${#nomModif}" >= 256 )) ; then # Vérifions si la longueur n'est pas excessive
((LongPath++))
echo "Le nom de chemin de fichier est trop long ! impossible de renommer '$nomOriginal' en '$nomModif'" >> "$log_error"
fi
if test -d "$nomOriginal"; then # si c' est un dossier
if test -e "$nomModif"; then # on verifie si il existe un dossier du meme nom avant de renommer
((NbRepNOTModified++))
echo "$NbRepNOTModified un dossier du meme nom existe deja : impossible de renommer '$nomOriginal' en '$nomModif'" >> "$log_error"
elif test ! -w "$(realpath "${nomOriginal}"/..)"; then # on verifie si le dossier parent est modifiable
((NbRepNOTModified++))
echo "permission refusée : impossible de renommer '$nomOriginal' en '$nomModif'"
echo "$NbRepNOTModified permission refusée : impossible de renommer '$nomOriginal' en '$nomModif'" >> "$log_error"
else # si pas de dossier du meme nom , on renomme
echo "dossier renommé : mkdir '$nomOriginal' ==> '$nomModif'"
if test "$modif_activ" = true; then
mkdir -p "$nomModif"
((NbRepModified++))
echo "$NbRepModified CREER_REP : mkdir '$nomModif'" >> "$log_modifs"
fi
fi
elif test -f "$nomOriginal" ; then # si c est un fichier
if test -e "$nomModif"; then # on verifie si il existe un fichier du meme nom avant de renommer et s ' il est modifiable
((NbFileNOTModified++))
echo "$NbFileNOTModified un fichier du meme nom existe deja : impossible de renommer '$nomOriginal' en '$nomModif'" >> "$log_error"
elif test ! -w "$(dirname "${nomOriginal}")"; then # on verifie si le dossier parent est modifiable
((NbFileNOTModified++))
echo "permission refusée : impossible de renommer '$nomOriginal' en '$nomModif'"
echo "$NbFileNOTModified : permission refusée : impossible de renommer '$nomOriginal' en '$nomModif'" >> "$log_error"
else # si pas de fichier du meme nom , on renomme
pathOriginal=${nomOriginal%/*} # chemin du repertoire original
pathModif=${nomModif%/*} # chemin apres modif
if [[ "$pathOriginal" != "$pathModif" ]]; then # si les chemins sont differents , c' est que l' arborescence a été modifiée :
nomModif="$pathModif"/"$nomArgModif" # dans ce cas on utilise l' arborescence modifiée precedemment + le nom modifié du dernier argument pour la destination
fi
echo "renommage du fichier : mv '$nomOriginal' ==> '$nomModif'"
if test "$modif_activ" = true; then
mv "$nomOriginal" "$nomModif"
NbFileModified+=1
echo "$NbFileModified RENOM : mv '$nomOriginal' en : '$nomModif'" >> "$log_modifs"
fi
fi
fi
fi
done
# --- Affichage récapitulatif ---
echo;
echo "récapitulatif :"
echo "$NbRepScanned dossiers et $NbFileScanned fichiers traités, $NbRepModified répertoires modifiés, $NbFileModified fichiers modifiés , le tout en $(($(date +%s)-Debut)) secondes."
(( NbNOTScanned )) && echo "$NbNOTScanned non traités."
echo;
(( NbFileModified || NbRepModified )) && echo "liste des dossiers et fichiers modifiés dans '/tmp/modifs'"
(( NbRepModified )) && echo "pour supprimer les dossiers vides , copiez collez la commande suivante : find '${execDir:=$PWD}' -type d -empty -delete"
echo;
if (( NbFileNOTModified || NbRepNOTModified || LongPath)); then
echo "$NbFileNOTModified fichiers , $NbRepNOTModified répertoires n ' ayant pas pu etre modifiés"
echo "vous avez $LongPath répertoires de taille trop importante."
echo "liste des erreurs : cat '$log_error'"
echo;
fiDernière modification par iznobe (Le 24/04/2026, à 10:34)
Hors ligne
#112 Le 24/04/2026, à 11:47
- iznobe

Re : [RESOLU] script mettre en conformité les noms de fichiers samba
Y a moyen certainement , de faire ça en plus " clair " :
elif test -f "$nomOriginal" ; then # si c est un fichier
if test ! -w "$(dirname "${nomOriginal}")"; then # on verifie si le dossier parent est modifiable
((NbFileNOTModified++))
echo "permission refusée : impossible de renommer '$nomOriginal' en '$nomModif'"
echo "$NbFileNOTModified : permission refusée : impossible de renommer '$nomOriginal' en '$nomModif'" >> "$log_error"
else
pathOriginal=${nomOriginal%/*} # chemin du repertoire original
pathModif=${nomModif%/*} # chemin apres modif
if [[ "$pathOriginal" != "$pathModif" ]]; then # si les chemins sont differents , c' est que l' arborescence a été modifiée :
nomModif="$pathModif"/"$nomArgModif" # dans ce cas on utilise l' arborescence modifiée precedemment + le nom modifié du dernier argument pour la destination
fi
# eviter les doublons et renommer correctement quand meme :
directory="$(dirname "$nomModif")"
name="${nomModif##*/}" # enlève le chemin
base="$name"
declare -i suffix=0
ext=""
while test -e "$nomModif"; do # Tant que le fichier cible existe déjà
if [[ "$name" == .* ]]; then
base="${name:1}" # enlève le point initial
if [[ "$base" == *.* ]]; then
ext=".${base##*.}"
base="${base%.*}"
fi
else
if [[ "$name" == *.* ]]; then
ext=".${name##*.}"
base="${name%.*}"
fi
fi
# Permet de renommer le tout ( les 4 possibilités ) , car $ext et $base sont definies au départ
nomModif="${directory}/${base}_${suffix}${ext}"
((suffix++))
done
echo "renommage du fichier : mv '$nomOriginal' ==> '$nomModif'"
if test "$modif_activ" = true; then
mv "$nomOriginal" "$nomModif"
NbFileModified+=1
echo "$NbFileModified RENOM : mv '$nomOriginal' en : '$nomModif'" >> "$log_modifs"
fi
fi
fi?
Dernière modification par iznobe (Le 24/04/2026, à 11:47)
Hors ligne
#113 Le 27/04/2026, à 14:18
- iznobe

Re : [RESOLU] script mettre en conformité les noms de fichiers samba
Bonjour , apres vérification , dans un script comme dans l ' autre , au niveau des " exclus " , ça ne fonctionne pas comme ça devrait .
En toute logique , avec l' exclu suivant : " LPT " , que ce soit lpt , lPt , lPT , LPT , LpT , etc .... ils devraient tous être suffixés , ce qui n' est pas le cas actuellement .
Comment y remédier ?
Hors ligne
#114 Le 27/04/2026, à 14:47
- iznobe

Re : [RESOLU] script mettre en conformité les noms de fichiers samba
#!/bin/bash
# Description des variables :
# $nomOriginal = nom complet rep ou fichier original
# $pathOriginal = chemin du repertoire original
# $nomModif = nom complet rep ou fichier modifié
# $pathModif = chemin du repertoire modifié
# $cleanFileName = nom fichier nettoyé
# FPNWE = chemin du fichier complet sans .ext = Full Path Name Without Extension
# $ext = extension du fichier le cas échéant sinon , renvoie le chemin complet du fichier.
# --- Configuration ---
modif_activ=false # true pour appliquer les modifications
execDir="" # Chemin ABSOLU du dossier cible (vide = PWD)
#### FIN ####
# --- Variables globales ---
declare -i LongPath=0 NbNOTScanned=0 NbRepScanned=0 NbFileScanned=0 NbRepModified=0 NbFileModified=0 NbRepNOTModified=0 NbFileNOTModified=0; Debut=$(date +%s);
declare log_error="/tmp/error.log" log_modifs="/tmp/modifs"
### Liste des fichiers exclus
#Exclus=( CON con PRN prn AUX aux NUL?L COM{0..9} com{0..9} LPT{0..9} lpt{0..9} COM¹ COM² COM³ com¹ com² com³ LPT¹ LPT² LPT³ lpt¹ lpt² lpt³ CLOCK$ clock$ )
Exclus=( CON PRN AUX NUL?L COM{0..9} LPT{0..9} COM¹ COM² COM³ LPT¹ LPT² LPT³ CLOCK$ )
# --- Initialisation ---
shopt -s globstar nullglob
echo "liste des erreurs ( fichiers ou dossiers ) n ' ayant pas pu etre modifiés :" > "$log_error"
echo "-------------------" > "$log_modifs"
clean_complete_name() { # Nettoie un nom de fichier/dossier
local name="$1"
# Nettoyage des espaces (début, fin, autour des /, multiples)
name=$(printf '%s' "$name" | sed -E '
s/^[[:space:]]+//;
s/[[:space:]]+$//;
s/[[:space:]]*\/[[:space:]]*/\//g;
s/[[:space:]]+/ /g
s/[[:space:]]*\.[[:space:]]*([^.]+)$/.\1/ # Suppression des espaces juste avant et / ou apres le dernier point
'| tr ''\''><"|?*\\:' '_________')
if [[ " ${Exclus[*]} " == *" $(echo "${name##*/}" | tr '[:lower:]' '[:upper:]') "* ]]
then name+="_";
fi
printf '%s\n' "$name"
}
for nomOriginal in "${execDir:=$PWD}"/**/*; do
if test -L "$nomOriginal"; then
((NbNOTScanned++))
continue
elif test -f "$nomOriginal"; then
((NbFileScanned++))
ext=${nomOriginal##*.} # get extension without filename
if test "$nomOriginal" != "$ext"; then # si le fichier comporte une extension
FPNWE="${nomOriginal%.*}" # get filename without extension
FPNWE=$(clean_complete_name "$FPNWE")
ext=$(clean_complete_name "$ext")
nomModif="$FPNWE.$ext"
else
nomModif=$(clean_complete_name "$nomOriginal")
fi
else
((NbRepScanned++))
nomModif=$(clean_complete_name "$nomOriginal")
fi
if [[ "$nomOriginal" != "$nomModif" ]]; then # si il y a un changement a effectuer
# le nom du chemin ne doit pas dépasser 256 en standard , et chemin étendu 32767 max , prefixe windows = "\\?\"
if (( "${#nomModif}" >= 256 )) ; then # Vérifions si la longueur n'est pas excessive
((LongPath++))
echo "Le nom de chemin de fichier est trop long ! impossible de renommer '$nomOriginal' en '$nomModif'" >> "$log_error"
fi
if test -d "$nomOriginal"; then # si c' est un dossier
if test ! -w "$(realpath "${nomOriginal}"/..)"; then # on verifie si le dossier parent est modifiable
((NbRepNOTModified++))
echo "permission refusée : impossible de renommer '$nomOriginal' en '$nomModif'"
echo "$NbRepNOTModified permission refusée : impossible de renommer '$nomOriginal' en '$nomModif'" >> "$log_error"
else # eviter les doublons et renommer correctement quand meme :
suffix=0
while test -e "$nomModif"; do # Tant que le dossier cible existe déjà
nomModif="${nomModif}_${suffix}"
((suffix++))
done
echo "dossier renommé : mkdir '$nomOriginal' ==> '$nomModif'"
if test "$modif_activ" = true; then
mkdir -pv "$nomModif"
((NbRepModified++))
echo "$NbRepModified CREER_REP : mkdir '$nomModif'" >> "$log_modifs"
fi
fi
elif test -f "$nomOriginal" ; then # si c est un fichier
if test ! -w "$(dirname "${nomOriginal}")"; then # on verifie si le dossier parent est modifiable
((NbFileNOTModified++))
echo "permission refusée : impossible de renommer '$nomOriginal' en '$nomModif'"
echo "$NbFileNOTModified : permission refusée : impossible de renommer '$nomOriginal' en '$nomModif'" >> "$log_error"
else
pathOriginal=${nomOriginal%/*} # chemin du repertoire original
pathModif=${nomModif%/*} # chemin apres modif
if [[ "$pathOriginal" != "$pathModif" ]]; then # si les chemins sont differents , c' est que l' arborescence a été modifiée :
nomModif="$pathModif"/"${nomModif##*/}" # dans ce cas on utilise l' arborescence modifiée precedemment + le nom modifié du dernier argument pour la destination
fi
# eviter les doublons et renommer correctement quand meme :
directory="${nomModif%/*}"
cleanFileName="${nomModif##*/}"
base="$cleanFileName"
ext=""
suffix=0
if [[ "$cleanFileName" == .* ]]; then
base="${cleanFileName:1}" # Fichier caché (ex: .bash_profile) , Enlève le point initial
if [[ "$base" == *.* ]]; then
ext=".${base##*.}"
base="${base%.*}"
fi
else
if [[ "$cleanFileName" == *.* ]]; then # Fichier normal (ex: fichier.txt)
ext=".${cleanFileName##*.}"
base="${cleanFileName%.*}"
fi
fi
while [[ -e "$nomModif" ]]; do
nomModif="${directory}/${base}_${suffix}${ext}"
((suffix++))
done
echo "renommage du fichier : mv '$nomOriginal' ==> '$nomModif'"
if test "$modif_activ" = true; then
mv "$nomOriginal" "$nomModif"
NbFileModified+=1
echo "$NbFileModified RENOM : mv '$nomOriginal' en : '$nomModif'" >> "$log_modifs"
fi
fi
fi
fi
done
echo;
echo "récapitulatif :"
echo "$NbRepScanned dossiers et $NbFileScanned fichiers traités, $NbRepModified répertoires modifiés, $NbFileModified fichiers modifiés , le tout en $(($(date +%s)-Debut)) secondes."
(( NbNOTScanned )) && echo "$NbNOTScanned non traités."
echo;
(( NbFileModified || NbRepModified )) && echo "Pour voir les modifications : cat '/tmp/modifs'"
(( NbRepModified )) && echo "pour supprimer les dossiers vides , copiez collez la commande suivante : find '${execDir:=$PWD}' -type d -empty -delete"
echo;
if (( NbFileNOTModified || NbRepNOTModified || LongPath)); then
echo "$NbFileNOTModified fichiers , $NbRepNOTModified répertoires n ' ayant pas pu etre modifiés"
echo "vous avez $LongPath répertoires de taille trop importante."
echo "liste des erreurs : cat '$log_error'"
echo;
fiOptimisation + correction pour les noms exclus apportée.
Dernière modification par iznobe (Le 27/04/2026, à 17:31)
Hors ligne
#115 Le 27/04/2026, à 21:55
- iznobe

Re : [RESOLU] script mettre en conformité les noms de fichiers samba
encore plus optimisé et traite plus de cas :
check_exclu() {
local name="$1"
if [[ " ${Exclus[*]} " == *" $(echo "${name##*/}" | tr '[:lower:]' '[:upper:]') "* ]]; then name+="_"; fi
printf '%s\n' "$name"
}
clean_name() { # Nettoie un nom de fichier/dossier
printf '%s' "$1" | sed -E '
s/^[[:space:]]+|[[:space:]]+$//g;
s/[[:space:]]*\/[[:space:]]*/\//g;
s/[[:space:]]+/ /g;
s/[[:space:]]*\.[[:space:]]*([^.]+)$/.\1/;
s/[^[:print:]]|['\''><"|?*\\:]/_/g
'
}Dernière modification par iznobe (Le 27/04/2026, à 22:10)
Hors ligne
#116 Le 27/04/2026, à 23:59
- Watael

Re : [RESOLU] script mettre en conformité les noms de fichiers samba
pas besoin de tr :
local name=${1^^}Connected \o/
Welcome to sHell. · eval is evil.
En ligne
#117 Le 28/04/2026, à 02:08
- MicP
Re : [RESOLU] script mettre en conformité les noms de fichiers samba
Bonjour
Une formulation plus courte de la ligne suivante :
Exclus=( CON PRN AUX NUL?L COM{0..9} LPT{0..9} COM¹ COM² COM³ LPT¹ LPT² LPT³ CLOCK$ )qui pourrait aussi s'écrire comme ça :
Exclus=( CON PRN AUX NUL?L {COM,LPT}{{0..9},¹,²,³} CLOCK$ )Hors ligne
#118 Le 28/04/2026, à 05:16
- Watael

Re : [RESOLU] script mettre en conformité les noms de fichiers samba
j'ai un gros doute sur NUL?L.
Connected \o/
Welcome to sHell. · eval is evil.
En ligne
#119 Le 28/04/2026, à 05:44
- MicP
Re : [RESOLU] script mettre en conformité les noms de fichiers samba
Effectivement, ça m'a fait aussi tiquer, mais je n'ai pas vraiment pris le temps de lire tout le script pour voir ce qui est fait avec ce NUL?L
Alors j'ai laissé tel quel.
Hors ligne
#120 Le 28/04/2026, à 07:53
- iznobe

Re : [RESOLU] script mettre en conformité les noms de fichiers samba
Bonjour , oui , finalement j ' ai changé aussi
n ' étant pas certain du truc a 100 % , de toute maniere , que ce soit avec " NUL?L " ou " NUL NULL " , ça ne fonctionne pas quand meme
.
le script a l ' heure d' aujourd hui :
#!/bin/bash
# Description des variables :
# $nomOriginal = nom complet rep ou fichier original
# $pathOriginal = chemin du repertoire original
# $nomModif = nom complet rep ou fichier modifié
# $pathModif = chemin du repertoire modifié
# $cleanFileName = nom fichier nettoyé
# FPNWE = chemin du fichier complet sans .ext = Full Path Name Without Extension
# $ext = extension du fichier le cas échéant sinon , renvoie le chemin complet du fichier.
# --- Configuration ---
modif_activ=false # true pour appliquer les modifications
execDir="" # Chemin ABSOLU du dossier cible (vide = PWD)
#### FIN ####
# --- Variables globales ---
declare -i count=0 LongPath=0 NbNOTScanned=0 NbRepScanned=0 NbFileScanned=0 NbRepModified=0 NbFileModified=0 NbRepNOTModified=0 NbFileNOTModified=0; Debut=$(date +%s);
declare log_error="/tmp/error.log" log_modifs="/tmp/modifs"
### Liste des fichiers exclus
Exclus=( CON PRN AUX NUL NULL COM{0..9} LPT{0..9} COM¹ COM² COM³ LPT¹ LPT² LPT³ CLOCK$ )
# --- Initialisation ---
shopt -s globstar nullglob
echo "liste des erreurs ( fichiers ou dossiers ) n ' ayant pas pu etre modifiés :" > "$log_error"
echo "-------------------" > "$log_modifs"
check_exclu() {
local name="$1"
if [[ " ${Exclus[*]} " == *" ${name^^{name##*/}} "* ]]; then name+="_"; fi
printf '%s\n' "$name"
}
clean_name() { # Nettoie un nom de fichier/dossier
printf '%s' "$1" | sed -E '
s/^[[:space:]]+|[[:space:]]+$//g;
s/[[:space:]]*\/[[:space:]]*/\//g;
s/[[:space:]]+/ /g;
s/[[:space:]]*\.[[:space:]]*([^.]+)$/.\1/;
s/[^[:print:]]|['\''><"|?*\\:]/_/g
#s/[^[:print:]]|[\/'\''><"|?*\\:]/_/g
'
}
for nomOriginal in "${execDir:=$PWD}"/**/*; do
if test -L "$nomOriginal"; then
((NbNOTScanned++))
continue
elif test -f "$nomOriginal"; then
((NbFileScanned++))
ext=${nomOriginal##*.} # get extension without filename
if test "$nomOriginal" != "$ext"; then # si le fichier comporte une extension
FPNWE="${nomOriginal%.*}" # get filename without extension
FPNWE=$(clean_name "$FPNWE")
FPNWE=$(check_exclu "$FPNWE")
ext=$(clean_name "$ext")
nomModif="$FPNWE.$ext"
else # si le fichier ne comporte pas d ' extension
nomModif=$(clean_name "$nomOriginal")
nomModif=$(check_exclu "$nomModif")
fi
else
((NbRepScanned++))
nomModif=$(clean_name "$nomOriginal")
nomModif=$(check_exclu "$nomModif")
fi
if [[ "$nomOriginal" != "$nomModif" ]]; then # si il y a un changement a effectuer
((count++))
# le nom du chemin ne doit pas dépasser 256 en standard , et chemin étendu 32767 max , prefixe windows = "\\?\"
if (( "${#nomModif}" >= 256 )) ; then # Vérifions si la longueur n'est pas excessive
((LongPath++))
echo "Le nom de chemin de fichier est trop long ! impossible de renommer '$nomOriginal' en '$nomModif'" >> "$log_error"
fi
if test -d "$nomOriginal"; then # si c' est un dossier
if test ! -w "$(realpath "${nomOriginal}"/..)"; then # on verifie si le dossier parent est modifiable
((NbRepNOTModified++))
echo "permission refusée : impossible de renommer '$nomOriginal' en '$nomModif'"
echo "$NbRepNOTModified permission refusée : impossible de renommer '$nomOriginal' en '$nomModif'" >> "$log_error"
else # eviter les doublons et renommer correctement quand meme :
suffix=0
while test -e "$nomModif"; do # Tant que le dossier cible existe déjà
nomModif="${nomModif}_${suffix}"
((suffix++))
done
echo "dossier renommé : mkdir '$nomOriginal' ==> '$nomModif'"
if test "$modif_activ" = true; then
mkdir -pv "$nomModif"
((NbRepModified++))
echo "$NbRepModified CREER_REP : mkdir '$nomModif'" >> "$log_modifs"
fi
fi
elif test -f "$nomOriginal" ; then # si c est un fichier
if test ! -w "$(dirname "${nomOriginal}")"; then # on verifie si le dossier parent est modifiable
((NbFileNOTModified++))
echo "permission refusée : impossible de renommer '$nomOriginal' en '$nomModif'"
echo "$NbFileNOTModified : permission refusée : impossible de renommer '$nomOriginal' en '$nomModif'" >> "$log_error"
else
pathOriginal=${nomOriginal%/*} # chemin du repertoire original
pathModif=${nomModif%/*} # chemin apres modif
if [[ "$pathOriginal" != "$pathModif" ]]; then # si les chemins sont differents , c' est que l' arborescence a été modifiée :
nomModif="$pathModif"/"${nomModif##*/}" # dans ce cas on utilise l' arborescence modifiée precedemment + le nom modifié du dernier argument pour la destination
fi
# eviter les doublons et renommer correctement quand meme :
directory="${nomModif%/*}"
cleanFileName="${nomModif##*/}"
base="$cleanFileName"
ext=""
suffix=0
if [[ "$cleanFileName" == .* ]]; then
base="${cleanFileName:1}" # Fichier caché (ex: .bash_profile) , Enlève le point initial
if [[ "$base" == *.* ]]; then
ext=".${base##*.}"
base="${base%.*}"
fi
else
if [[ "$cleanFileName" == *.* ]]; then # Fichier normal (ex: fichier.txt)
ext=".${cleanFileName##*.}"
base="${cleanFileName%.*}"
fi
fi
while [[ -e "$nomModif" ]]; do
nomModif="${directory}/${base}_${suffix}${ext}"
((suffix++))
done
echo "renommage du fichier : mv '$nomOriginal' ==> '$nomModif'"
if test "$modif_activ" = true; then
mv "$nomOriginal" "$nomModif"
NbFileModified+=1
echo "$NbFileModified RENOM : mv '$nomOriginal' en : '$nomModif'" >> "$log_modifs"
fi
fi
fi
fi
done
echo;
echo "récapitulatif : modif count = $count"
echo "$NbRepScanned dossiers et $NbFileScanned fichiers traités, $NbRepModified répertoires modifiés, $NbFileModified fichiers modifiés , le tout en $(($(date +%s)-Debut)) secondes."
(( NbNOTScanned )) && echo "$NbNOTScanned non traités."
echo;
(( NbFileModified || NbRepModified )) && echo "Pour voir les modifications : cat '/tmp/modifs'"
(( NbRepModified )) && echo "pour supprimer les dossiers vides , copiez collez la commande suivante : find '${execDir:=$PWD}' -type d -empty -delete"
echo;
if (( NbFileNOTModified || NbRepNOTModified || LongPath)); then
echo "$NbFileNOTModified fichiers , $NbRepNOTModified répertoires n ' ayant pas pu etre modifiés"
echo "vous avez $LongPath répertoires de taille trop importante."
echo "liste des erreurs : cat '$log_error'"
echo;
fij ' ai pris le temps optimiser le script santize , avec un seul awk , c ' est beaucoup mieux que 10 sed
.
Aussi en passant des paramètres " pur bash " , c ' est beaucoup mieux .
Cependant il subsiste une erreur entre les 2 que je n' arrive pas ni a trouver ni a corriger .
il semblerait que dans le samba rename , les espaces autour de tous les " / " soient gérés , et que ce n' est pas le cas dans le sanitize .
Toujours est il que dans certains cas , certain fichiers sont modifiés par le script samba_rename ( au dessus ) , et pas par le sanitize :
#!/bin/bash
sanitize() {
shopt -s extglob
filename=${1##*/}
directory=${1%/*}
name_clean=$(
printf '%s' "$filename" |
awk '
BEGIN {
IGNORECASE = 1
reserved["nul"]; reserved["prn"]; reserved["con"]; reserved["aux"]
for (i=0;i<=9;i++) { reserved["com" i]; reserved["lpt" i] }
reserved["com¹"]; reserved["com²"]; reserved["com³"]
reserved["lpt¹"]; reserved["lpt²"]; reserved["lpt³"]
}
{
# trim
gsub(/^[[:space:]]+|[[:space:]]+$/, "")
# espaces autour /
gsub(/[[:space:]]*\/[[:space:]]*/, "/")
# espaces multiples
gsub(/[[:space:]]+/, " ")
# caractères interdits + contrôle
gsub(/['"'"'\\/:\*\?\"<>\|\001-\037\177]/, "_")
# suppression points finaux
sub(/\.+$/, "")
# nettoyage dernier point
if (match($0, /[[:space:]]*\.[[:space:]]*([^.]+)$/)) {
ext = substr($0, RSTART, RLENGTH)
sub(/^[[:space:]]*\.[[:space:]]*/, ".", ext)
$0 = substr($0, 1, RSTART-1) ext
}
# uniquement des points → vide
if ($0 ~ /^\.*$/) $0=""
# basename sans extension
base = $0
sub(/\..*$/, "", base)
if (tolower(base) in reserved) {
$0 = base "_" substr($0, length(base)+1)
}
# vide → NONAME
if ($0 ~ /^[[:space:]]*$/) $0="NONAME"
print
}'
)
if test "$filename" != "$name_clean"; then
suffix=0
final_name="$directory/$name_clean"
name="${name_clean##*/}"
base="$name"
ext=""
if [[ "$name" == .* ]]; then
base="${name:1}"
if [[ "$base" == *.* ]]; then
ext="${base##*.}"
base="${base%.*}"
fi
else
if [[ "$name" == *.* ]]; then
ext="${name##*.}"
base="${name%.*}"
fi
fi
while test -e "$final_name"; do
final_name="${directory}/${base}_${suffix}${ext}"
((suffix++))
done
echo " => '$1' serait renommé en '$final_name'"
#mv -v "$1" "$final_name" >> /tmp/sanitize.log
fi
}
export -f sanitize
sanitize_dir() {
Debut=$(date +%s);
find "$1" -depth -exec bash -c 'sanitize "$0"' {} \;
echo "le tout en $(($(date +%s)-Debut)) secondes."
}
sanitize_dir "$PWD"Un nom a problème par exemple : ' test . pour . fun . ext '
Dernière modification par iznobe (Le 28/04/2026, à 08:20)
Hors ligne
#121 Le 28/04/2026, à 08:27
- iznobe

Re : [RESOLU] script mettre en conformité les noms de fichiers samba
pas besoin de tr :
local name=${1^^}
En fait , j ' ai pas trouvé comment faire un truc propre .
ça fonctionne :
check_exclu() {
local name="$1"
if [[ " ${Exclus[*]} " == *" $(echo "${name##*/}" | tr '[:lower:]' '[:upper:]') "* ]]; then name+="_"; fi
printf '%s\n' "$name"
}les autres trucs avec " ^^ " , pas .
obtenu lorsque ça fonctionne :
iznobe@iznobe-PC-U26:~/Scripts/test$ bash ~/Scripts/rename.sh
dossier renommé : mkdir '/home/iznobe/Scripts/test/com¹' ==> '/home/iznobe/Scripts/test/com¹_'
renommage du fichier : mv '/home/iznobe/Scripts/test/con' ==> '/home/iznobe/Scripts/test/con_'
renommage du fichier : mv '/home/iznobe/Scripts/test/CoN' ==> '/home/iznobe/Scripts/test/CoN_'
renommage du fichier : mv '/home/iznobe/Scripts/test/lpt2' ==> '/home/iznobe/Scripts/test/lpt2_'
renommage du fichier : mv '/home/iznobe/Scripts/test/lpt²' ==> '/home/iznobe/Scripts/test/lpt²_'
renommage du fichier : mv '/home/iznobe/Scripts/test/LPT3' ==> '/home/iznobe/Scripts/test/LPT3_'
renommage du fichier : mv '/home/iznobe/Scripts/test/nul' ==> '/home/iznobe/Scripts/test/nul_'
renommage du fichier : mv '/home/iznobe/Scripts/test/nUl' ==> '/home/iznobe/Scripts/test/nUl_'
renommage du fichier : mv '/home/iznobe/Scripts/test/NuLl' ==> '/home/iznobe/Scripts/test/NuLl_'
renommage du fichier : mv '/home/iznobe/Scripts/test/prn' ==> '/home/iznobe/Scripts/test/prn_'
renommage du fichier : mv '/home/iznobe/Scripts/test/ PrN . txt ' ==> '/home/iznobe/Scripts/test/PrN_.txt'
renommage du fichier : mv '/home/iznobe/Scripts/test/ test . pour . fun . ext ' ==> '/home/iznobe/Scripts/test/test . pour.fun.ext'
renommage du fichier : mv '/home/iznobe/Scripts/test/ v etrtrsde . point ' ==> '/home/iznobe/Scripts/test/v etrtrsde.point'
récapitulatif : modif count = 13
1 dossiers et 14 fichiers traités, 0 répertoires modifiés, 0 fichiers modifiés , le tout en 0 secondes.
iznobe@iznobe-PC-U26:~/Scripts/test$ un des trucs tester qui ne fonctionne pas :
.
check_exclu() {
local name="$1"
if [[ " ${Exclus[*]} " == *" ${name##*/^^} "* ]]; then name+="_"; fi
printf '%s\n' "$name"
}un autre :
check_exclu() {
local name="$1"
if [[ " ${Exclus[*]} " == *" ${name^^{name##*/}} "* ]]; then name+="_"; fi
printf '%s\n' "$name"
}Encore un :
check_exclu() {
local name="$1"
if [[ " ${Exclus[*]} " == *" ${name^^"${name##*/}"} "* ]]; then name+="_"; fi
printf '%s\n' "$name"
}Dans les autres cas , j ' ai obtenu :
iznobe@iznobe-PC-U26:~/Scripts/test$ bash ~/Scripts/rename.sh
renommage du fichier : mv '/home/iznobe/Scripts/test/ PrN . txt ' ==> '/home/iznobe/Scripts/test/PrN.txt'
renommage du fichier : mv '/home/iznobe/Scripts/test/ test . pour . fun . ext ' ==> '/home/iznobe/Scripts/test/test . pour.fun.ext'
renommage du fichier : mv '/home/iznobe/Scripts/test/ v etrtrsde . point ' ==> '/home/iznobe/Scripts/test/v etrtrsde.point'
récapitulatif : modif count = 3
1 dossiers et 14 fichiers traités, 0 répertoires modifiés, 0 fichiers modifiés , le tout en 0 secondes.
iznobe@iznobe-PC-U26:~/Scripts/test$ et si je "sors" de la condition :
check_exclu() {
local name="$1"
name="${name^^}"
if [[ " ${Exclus[*]} " == *" $(echo "${name##*/}") "* ]]; then name+="_"; fi
printf '%s\n' "$name"
} alors tous les noms sont renommés en majuscules
:
iznobe@iznobe-PC-U26:~/Scripts/test$ bash ~/Scripts/rename.sh
dossier renommé : mkdir '/home/iznobe/Scripts/test/com¹' ==> '/HOME/IZNOBE/SCRIPTS/TEST/COM¹_'
renommage du fichier : mv '/home/iznobe/Scripts/test/com 2' ==> '/HOME/IZNOBE/SCRIPTS/TEST/COM 2'
renommage du fichier : mv '/home/iznobe/Scripts/test/con' ==> '/HOME/IZNOBE/SCRIPTS/TEST/CON_'
renommage du fichier : mv '/home/iznobe/Scripts/test/CoN' ==> '/HOME/IZNOBE/SCRIPTS/TEST/CON_'
renommage du fichier : mv '/home/iznobe/Scripts/test/lpt2' ==> '/HOME/IZNOBE/SCRIPTS/TEST/LPT2_'
renommage du fichier : mv '/home/iznobe/Scripts/test/lpt²' ==> '/HOME/IZNOBE/SCRIPTS/TEST/LPT²_'
renommage du fichier : mv '/home/iznobe/Scripts/test/LPT3' ==> '/HOME/IZNOBE/SCRIPTS/TEST/LPT3_'
renommage du fichier : mv '/home/iznobe/Scripts/test/nul' ==> '/HOME/IZNOBE/SCRIPTS/TEST/NUL_'
renommage du fichier : mv '/home/iznobe/Scripts/test/nUl' ==> '/HOME/IZNOBE/SCRIPTS/TEST/NUL_'
renommage du fichier : mv '/home/iznobe/Scripts/test/NuLl' ==> '/HOME/IZNOBE/SCRIPTS/TEST/NULL_'
renommage du fichier : mv '/home/iznobe/Scripts/test/pecon12' ==> '/HOME/IZNOBE/SCRIPTS/TEST/PECON12'
renommage du fichier : mv '/home/iznobe/Scripts/test/prn' ==> '/HOME/IZNOBE/SCRIPTS/TEST/PRN_'
renommage du fichier : mv '/home/iznobe/Scripts/test/ PrN . txt ' ==> '/HOME/IZNOBE/SCRIPTS/TEST/PRN_.txt'
renommage du fichier : mv '/home/iznobe/Scripts/test/ test . pour . fun . ext ' ==> '/HOME/IZNOBE/SCRIPTS/TEST/TEST . POUR.FUN.ext'
renommage du fichier : mv '/home/iznobe/Scripts/test/ v etrtrsde . point ' ==> '/HOME/IZNOBE/SCRIPTS/TEST/V ETRTRSDE.point'
récapitulatif : modif count = 15
1 dossiers et 14 fichiers traités, 0 répertoires modifiés, 0 fichiers modifiés , le tout en 0 secondes.Dernière modification par iznobe (Le 28/04/2026, à 12:44)
Hors ligne
#122 Le 28/04/2026, à 12:54
- Watael

Re : [RESOLU] script mettre en conformité les noms de fichiers samba
split le chemin et le nom.
checkExclu() {
local name=${1##*/} path=${1%/*}
if [[ " ${Exclus[*]} " == *" ${name^^}"* ]]; then name+="_"; fi
echo "$path/$name"
}Edit: correction inversion path <-> name
Dernière modification par Watael (Le 28/04/2026, à 15:28)
Connected \o/
Welcome to sHell. · eval is evil.
En ligne
#123 Le 28/04/2026, à 13:38
- iznobe

Re : [RESOLU] script mettre en conformité les noms de fichiers samba
bon finalement avec , :
check_exclu() {
local name="$1"
local base="${name##*/}"
if [[ " ${Exclus[*]} " == *" ${base^^} "* ]]; then name+="_"; fi
printf '%s\n' "$name"
}ça passe .
@Watael , avec ta version , j ' obtenais :
iznobe@iznobe-PC-U26:~/Scripts/test$ bash ~/Scripts/rename.sh
dossier renommé : mkdir '/home/iznobe/Scripts/test/com¹' ==> 'com¹//home/iznobe/Scripts/test'
renommage du fichier : mv '/home/iznobe/Scripts/test/com 2' ==> 'com 2//home/iznobe/Scripts/test'
renommage du fichier : mv '/home/iznobe/Scripts/test/con' ==> 'con//home/iznobe/Scripts/test'
renommage du fichier : mv '/home/iznobe/Scripts/test/CoN' ==> 'CoN//home/iznobe/Scripts/test'
renommage du fichier : mv '/home/iznobe/Scripts/test/lpt2' ==> 'lpt2//home/iznobe/Scripts/test'
renommage du fichier : mv '/home/iznobe/Scripts/test/lpt²' ==> 'lpt²//home/iznobe/Scripts/test'
renommage du fichier : mv '/home/iznobe/Scripts/test/LPT3' ==> 'LPT3//home/iznobe/Scripts/test'
renommage du fichier : mv '/home/iznobe/Scripts/test/nul' ==> 'nul//home/iznobe/Scripts/test'
renommage du fichier : mv '/home/iznobe/Scripts/test/nUl' ==> 'nUl//home/iznobe/Scripts/test'
renommage du fichier : mv '/home/iznobe/Scripts/test/NuLl' ==> 'NuLl//home/iznobe/Scripts/test'
renommage du fichier : mv '/home/iznobe/Scripts/test/pecon12' ==> 'pecon12//home/iznobe/Scripts/test'
renommage du fichier : mv '/home/iznobe/Scripts/test/prn' ==> 'prn//home/iznobe/Scripts/test'
renommage du fichier : mv '/home/iznobe/Scripts/test/ PrN . txt ' ==> 'PrN.txt/PrN.txt'
renommage du fichier : mv '/home/iznobe/Scripts/test/ test . pour . fun . ext ' ==> 'test . pour . fun.ext/test . pour . fun.ext'
renommage du fichier : mv '/home/iznobe/Scripts/test/ v etrtrsde . point ' ==> 'v etrtrsde.point/v etrtrsde.point'
récapitulatif : modif count = 15
1 dossiers et 14 fichiers traités, 0 répertoires modifiés, 0 fichiers modifiés , le tout en 0 secondes.Mais ça m ' a mis sur la bonne voie ![]()
j ' ai remplacé dans la fonctions tous les sed par le awk .
j ' ai changé la logique de correction des fichiers avec extensions :
elif test -f "$nomOriginal"; then
((NbFileScanned++))
ext=${nomOriginal##*.} # get extension without filename
if test "$nomOriginal" != "$ext"; then # si le fichier comporte une extension
FP=$(clean_name "$nomOriginal")
FP=$(check_exclu "$FP")
FPNWE=${FP%.*} # get filename without extension
ext=$(clean_name "$ext")
nomModif="$FPNWE.$ext"car c' est elle qui induisait le bug des espaces devant les points , en déplaçant le dernier point ....
et là on commence a avoir quelquechose de vraiment pas mal ( scanne en 3 fois plus rapide que le sanitize.sh ! ) avec exactement les même résultats , les logs et les comptes en prime
:
#!/bin/bash
# Description des variables :
# $nomOriginal = nom complet rep ou fichier original
# $pathOriginal = chemin du repertoire original
# $nomModif = nom complet rep ou fichier modifié
# $pathModif = chemin du repertoire modifié
# $cleanFileName = nom fichier nettoyé
# FPNWE = chemin du fichier complet sans .ext = Full Path Name Without Extension
# $ext = extension du fichier le cas échéant sinon , renvoie le chemin complet du fichier.
# --- Configuration ---
modif_activ=false # true pour appliquer les modifications
execDir="" # Chemin ABSOLU du dossier cible (vide = PWD)
#### FIN ####
# --- Variables globales ---
declare -i count=0 LongPath=0 NbNOTScanned=0 NbRepScanned=0 NbFileScanned=0 NbRepModified=0 NbFileModified=0 NbRepNOTModified=0 NbFileNOTModified=0; Debut=$(date +%s);
declare log_error="/tmp/error.log" log_modifs="/tmp/modifs"
### Liste des fichiers exclus
Exclus=( CON PRN AUX NUL NULL COM{0..9} LPT{0..9} COM¹ COM² COM³ LPT¹ LPT² LPT³ CLOCK$ )
# --- Initialisation ---
shopt -s globstar nullglob
echo "liste des erreurs ( fichiers ou dossiers ) n ' ayant pas pu etre modifiés :" > "$log_error"
echo "-------------------" > "$log_modifs"
check_exclu() {
local name="$1"
local base="${name##*/}"
if [[ " ${Exclus[*]} " == *" ${base^^} "* ]]; then name+="_"; fi
printf '%s\n' "$name"
}
clean_name() { # Nettoie un nom de fichier/dossier
printf '%s' "$1" | awk '
BEGIN {
IGNORECASE = 1
reserved["nul"]; reserved["prn"]; reserved["con"]; reserved["aux"]
for (i=0;i<=9;i++) { reserved["com" i]; reserved["lpt" i] }
reserved["com¹"]; reserved["com²"]; reserved["com³"]
reserved["lpt¹"]; reserved["lpt²"]; reserved["lpt³"]
}
{
# trim
gsub(/^[[:space:]]+|[[:space:]]+$/, "")
# espaces autour /
gsub(/[[:space:]]*\/[[:space:]]*/, "/")
# espaces multiples
gsub(/[[:space:]]+/, " ")
# caractères interdits + contrôle
gsub(/['"'"'\\:\*\?\"<>\|\001-\037\177]/, "_")
# suppression points finaux
sub(/\.+$/, "")
# nettoyage dernier point
if (match($0, /[[:space:]]*\.[[:space:]]*([^.]+)$/)) {
ext = substr($0, RSTART, RLENGTH)
sub(/^[[:space:]]*\.[[:space:]]*/, ".", ext)
$0 = substr($0, 1, RSTART-1) ext
}
# uniquement des points → vide
if ($0 ~ /^\.*$/) $0=""
# basename sans extension
base = $0
sub(/\..*$/, "", base)
if (tolower(base) in reserved) {
$0 = base "_" substr($0, length(base)+1)
}
# vide → NONAME
if ($0 ~ /^[[:space:]]*$/) $0="NONAME"
print
}'
}
for nomOriginal in "${execDir:=$PWD}"/**/*; do
if test -L "$nomOriginal"; then
((NbNOTScanned++))
continue
elif test -f "$nomOriginal"; then
((NbFileScanned++))
ext=${nomOriginal##*.} # get extension without filename
if test "$nomOriginal" != "$ext"; then # si le fichier comporte une extension
FP=$(clean_name "$nomOriginal")
FP=$(check_exclu "$FP")
FPNWE=${FP%.*} # get filename without extension
ext=$(clean_name "$ext")
nomModif="$FPNWE.$ext"
else # si le fichier ne comporte pas d ' extension
nomModif=$(clean_name "$nomOriginal")
nomModif=$(check_exclu "$nomModif")
fi
else
((NbRepScanned++))
nomModif=$(clean_name "$nomOriginal")
nomModif=$(check_exclu "$nomModif")
fi
if [[ "$nomOriginal" != "$nomModif" ]]; then # si il y a un changement a effectuer
((count++))
# le nom du chemin ne doit pas dépasser 256 en standard , et chemin étendu 32767 max , prefixe windows = "\\?\"
if (( "${#nomModif}" >= 256 )) ; then # Vérifions si la longueur n'est pas excessive
((LongPath++))
echo "Le nom de chemin de fichier est trop long ! impossible de renommer '$nomOriginal' en '$nomModif'" >> "$log_error"
fi
if test -d "$nomOriginal"; then # si c' est un dossier
if test ! -w "$(realpath "${nomOriginal}"/..)"; then # on verifie si le dossier parent est modifiable
((NbRepNOTModified++))
echo "permission refusée : impossible de renommer '$nomOriginal' en '$nomModif'"
echo "$NbRepNOTModified permission refusée : impossible de renommer '$nomOriginal' en '$nomModif'" >> "$log_error"
else # eviter les doublons et renommer correctement quand meme :
suffix=0
while test -e "$nomModif"; do # Tant que le dossier cible existe déjà
nomModif="${nomModif}_${suffix}"
((suffix++))
done
echo "dossier renommé : mkdir '$nomOriginal' ==> '$nomModif'"
if test "$modif_activ" = true; then
mkdir -pv "$nomModif"
((NbRepModified++))
echo "$NbRepModified CREER_REP : mkdir '$nomModif'" >> "$log_modifs"
fi
fi
elif test -f "$nomOriginal" ; then # si c est un fichier
if test ! -w "$(dirname "${nomOriginal}")"; then # on verifie si le dossier parent est modifiable
((NbFileNOTModified++))
echo "permission refusée : impossible de renommer '$nomOriginal' en '$nomModif'"
echo "$NbFileNOTModified : permission refusée : impossible de renommer '$nomOriginal' en '$nomModif'" >> "$log_error"
else
pathOriginal=${nomOriginal%/*} # chemin du repertoire original
pathModif=${nomModif%/*} # chemin apres modif
if [[ "$pathOriginal" != "$pathModif" ]]; then # si les chemins sont differents , c' est que l' arborescence a été modifiée :
nomModif="$pathModif"/"${nomModif##*/}" # dans ce cas on utilise l' arborescence modifiée precedemment + le nom modifié du dernier argument pour la destination
fi
# eviter les doublons et renommer correctement quand meme :
directory="${nomModif%/*}"
cleanFileName="${nomModif##*/}"
base="$cleanFileName"
ext=""
suffix=0
if [[ "$cleanFileName" == .* ]]; then
base="${cleanFileName:1}" # Fichier caché (ex: .bash_profile) , Enlève le point initial
if [[ "$base" == *.* ]]; then
ext=".${base##*.}"
base="${base%.*}"
fi
else
if [[ "$cleanFileName" == *.* ]]; then # Fichier normal (ex: fichier.txt)
ext=".${cleanFileName##*.}"
base="${cleanFileName%.*}"
fi
fi
while [[ -e "$nomModif" ]]; do
nomModif="${directory}/${base}_${suffix}${ext}"
((suffix++))
done
echo "renommage du fichier : mv '$nomOriginal' ==> '$nomModif'"
if test "$modif_activ" = true; then
mv "$nomOriginal" "$nomModif"
NbFileModified+=1
echo "$NbFileModified RENOM : mv '$nomOriginal' en : '$nomModif'" >> "$log_modifs"
fi
fi
fi
fi
done
echo;
echo "récapitulatif : modif count = $count"
echo "$NbRepScanned dossiers et $NbFileScanned fichiers traités, $NbRepModified répertoires modifiés, $NbFileModified fichiers modifiés , le tout en $(($(date +%s)-Debut)) secondes."
(( NbNOTScanned )) && echo "$NbNOTScanned non traités."
echo;
(( NbFileModified || NbRepModified )) && echo "Pour voir les modifications : cat '/tmp/modifs'"
(( NbRepModified )) && echo "pour supprimer les dossiers vides , copiez collez la commande suivante : find '${execDir:=$PWD}' -type d -empty -delete"
echo;
if (( NbFileNOTModified || NbRepNOTModified || LongPath)); then
echo "$NbFileNOTModified fichiers , $NbRepNOTModified répertoires n ' ayant pas pu etre modifiés"
echo "vous avez $LongPath répertoires de taille trop importante."
echo "liste des erreurs : cat '$log_error'"
echo;
fiDernière modification par iznobe (Le 28/04/2026, à 13:53)
Hors ligne
#124 Le 28/04/2026, à 15:35
- iznobe

Re : [RESOLU] script mettre en conformité les noms de fichiers samba
Maintenant que la fonction marche .... pourquoi est ce que le awk ne fait pas cette partie du travail ?
clean_name() { # Nettoie un nom de fichier/dossier
printf '%s' "$1" | awk '
BEGIN {
IGNORECASE = 1reserved["NUL"]; reserved["PRN"]; reserved["CON"]; reserved["AUX"]
for (i=0;i<=9;i++) { reserved["COM" i]; reserved["LPT" i] }
reserved["COM¹"]; reserved["COM²"]; reserved["COM³"]
reserved["LPT¹"]; reserved["LPT²"]; reserved["LPT³"]
}
{
# trim
gsub(/^[[:space:]]+|[[:space:]]+$/, "")# espaces autour /
gsub(/[[:space:]]*\/[[:space:]]*/, "/")# espaces multiples
gsub(/[[:space:]]+/, " ")# caractères interdits + contrôle
gsub(/['"'"'\\:\*\?\"<>\|\001-\037\177]/, "_")# suppression points finaux
sub(/\.+$/, "")# nettoyage dernier point
if (match($0, /[[:space:]]*\.[[:space:]]*([^.]+)$/)) {
ext = substr($0, RSTART, RLENGTH)
sub(/^[[:space:]]*\.[[:space:]]*/, ".", ext)
$0 = substr($0, 1, RSTART-1) ext
}# uniquement des points → vide
if ($0 ~ /^\.*$/) $0=""# basename sans extension
base = $0
sub(/\..*$/, "", base)if (toupper(base) in reserved) { $0 = base "_" substr($0, length(base)+1) }# vide → NONAME
if ($0 ~ /^[[:space:]]*$/) $0="NONAME"
}'
}
Dernière modification par iznobe (Le 28/04/2026, à 16:32)
Hors ligne
#125 Le 28/04/2026, à 17:41
- iznobe

Re : [RESOLU] script mettre en conformité les noms de fichiers samba
Du coup nettoyage du code et re optimisation :
il doit bien rester quelques broutilles , non ?
ben voui , j ' allais oublié la recirculation en cas de déplacement / renommage de dossier :
#!/bin/bash
# Description des variables :
# $nomOriginal = nom complet rep ou fichier original
# $pathOriginal = chemin du repertoire original
# $nomModif = nom complet rep ou fichier modifié
# $pathModif = chemin du repertoire modifié
# $cleanFileName = nom fichier nettoyé
# FPNWE = chemin du fichier complet sans .ext = Full Path Name Without Extension
# $ext = extension du fichier le cas échéant sinon , renvoie le chemin complet du fichier.
# --- Configuration ---
modif_activ=false # true pour appliquer les modifications
#### FIN ####
# --- Variables globales ---
declare -i count=0 LongPath=0 NbNOTScanned=0 NbRepScanned=0 NbFileScanned=0 NbRepModified=0 NbFileModified=0 NbRepNOTModified=0 NbFileNOTModified=0; Debut=$(date +%s);
declare log_error="/tmp/error.log" log_modifs="/tmp/modifs"
# --- Initialisation ---
shopt -s globstar nullglob
test -z "$log_error" && echo "liste des erreurs ( fichiers ou dossiers ) n ' ayant pas pu etre modifiés :" > "$log_error"
test -z "$log_modifs" && echo "-------------------" > "$log_modifs"
execDir="$1"
clean_name() { # Nettoie un nom de fichier/dossier
printf '%s' "$1" | awk '
BEGIN {
IGNORECASE = 1
reserved["NUL"]; reserved["NULL"]; reserved["PRN"]; reserved["CON"]; reserved["AUX"]; reserved["CLOCK$"]
for (i=0;i<=9;i++) { reserved["COM" i]; reserved["LPT" i] }
reserved["COM¹"]; reserved["COM²"]; reserved["COM³"]
reserved["LPT¹"]; reserved["LPT²"]; reserved["LPT³"]
}
{
# trim
gsub(/^[[:space:]]+|[[:space:]]+$/, "")
# espaces autour /
gsub(/[[:space:]]*\/[[:space:]]*/, "/")
# espaces multiples
gsub(/[[:space:]]+/, " ")
# caractères interdits + contrôle
gsub(/['\''"\\:\*\?\"<>\|\001-\037\177]/, "_")
# suppression points finaux
sub(/\.+$/, "")
# nettoyage dernier point
if (match($0, /[[:space:]]*\.[[:space:]]*([^.]+)$/)) {
ext = substr($0, RSTART, RLENGTH)
sub(/^[[:space:]]*\.[[:space:]]*/, ".", ext)
$0 = substr($0, 1, RSTART-1) ext
}
# uniquement des points → vide
if ($0 ~ /^\.*$/) $0=""
# basename sans extension
base = $0
sub(/\..*$/, "", base)
if (toupper(base) in reserved) {
$0 = base "_" substr($0, length(base)+1)
}
# vide → NONAME
if ($0 ~ /^[[:space:]]*$/) $0="NONAME"
print # <-- Ici, le print est bien dans le bloc !
}'
}
for nomOriginal in "${execDir:=$PWD}"/**/*; do
if test -L "$nomOriginal"; then
((NbNOTScanned++))
continue
fi
pathOriginal="${nomOriginal%/*}" # get original pathname
file="${nomOriginal##*/}" # get file name or directory name
if test -f "$nomOriginal"; then
((NbFileScanned++))
else
((NbRepScanned++))
fi
nomModif="$pathOriginal/$(clean_name "$file")"
###############################"
if [[ "$nomOriginal" != "$nomModif" ]]; then # si il y a un changement a effectuer
((count++))
# le nom du chemin ne doit pas dépasser 256 en standard , et chemin étendu 32767 max , prefixe windows = "\\?\"
if (( "${#nomModif}" >= 256 )) ; then # Vérifions si la longueur n'est pas excessive
((LongPath++))
echo "Le nom de chemin de fichier est trop long ! impossible de renommer '$nomOriginal' en '$nomModif'" >> "$log_error"
fi
if test -d "$nomOriginal"; then # si c' est un dossier
if test ! -w "$(realpath "${nomOriginal}"/..)"; then # on verifie si le dossier parent est modifiable
((NbRepNOTModified++))
echo "permission refusée : impossible de renommer '$nomOriginal' en '$nomModif'"
echo "$NbRepNOTModified permission refusée : impossible de renommer '$nomOriginal' en '$nomModif'" >> "$log_error"
else # eviter les doublons et renommer correctement quand meme :
suffix=0
while test -e "$nomModif"; do # Tant que le dossier cible existe déjà
nomModif="${nomModif}_${suffix}"
((suffix++))
done
echo "dossier renommé : mkdir '$nomOriginal' ==> '$nomModif'"
if test "$modif_activ" = true; then
mv -v "$nomOriginal" "$nomModif"
((NbRepModified++))
echo "$NbRepModified CREER_REP : mkdir '$nomModif'" >> "$log_modifs"
bash "$0" "$nomModif"
fi
fi
elif test -f "$nomOriginal" ; then # si c est un fichier
if test ! -w "$(dirname "${nomOriginal}")"; then # on verifie si le dossier parent est modifiable
((NbFileNOTModified++))
echo "permission refusée : impossible de renommer '$nomOriginal' en '$nomModif'"
echo "$NbFileNOTModified : permission refusée : impossible de renommer '$nomOriginal' en '$nomModif'" >> "$log_error"
else
pathModif=${nomModif%/*} # chemin apres modif
if [[ "$pathOriginal" != "$pathModif" ]]; then # si les chemins sont differents , c' est que l' arborescence a été modifiée :
nomModif="$pathModif"/"${nomModif##*/}" # dans ce cas on utilise l' arborescence modifiée precedemment + le nom modifié du dernier argument pour la destination
fi
# eviter les doublons et renommer correctement quand meme :
directory="${nomModif%/*}"
cleanFileName="${nomModif##*/}"
base="$cleanFileName"
ext=""
suffix=0
if [[ "$cleanFileName" == .* ]]; then
base="${cleanFileName:1}" # Fichier caché (ex: .bash_profile) , Enlève le point initial
if [[ "$base" == *.* ]]; then
ext=".${base##*.}"
base="${base%.*}"
fi
else
if [[ "$cleanFileName" == *.* ]]; then # Fichier normal (ex: fichier.txt)
ext=".${cleanFileName##*.}"
base="${cleanFileName%.*}"
fi
fi
while [[ -e "$nomModif" ]]; do
nomModif="${directory}/${base}_${suffix}${ext}"
((suffix++))
done
echo "renommage du fichier : mv '$nomOriginal' ==> '$nomModif'"
if test "$modif_activ" = true; then
mv "$nomOriginal" "$nomModif"
NbFileModified+=1
echo "$NbFileModified RENOM : mv '$nomOriginal' en : '$nomModif'" >> "$log_modifs"
fi
fi
fi
fi
done
echo;
echo "récapitulatif : modif count = $count"
echo "$NbRepScanned dossiers et $NbFileScanned fichiers traités, $NbRepModified répertoires modifiés, $NbFileModified fichiers modifiés , le tout en $(($(date +%s)-Debut)) secondes."
(( NbNOTScanned )) && echo "$NbNOTScanned non traités."
echo;
(( NbFileModified || NbRepModified )) && echo "Pour voir les modifications : cat '/tmp/modifs'"
(( NbRepModified )) && echo "pour supprimer les dossiers vides , copiez collez la commande suivante : find '${execDir:=$PWD}' -type d -empty -delete"
echo;
if (( NbFileNOTModified || NbRepNOTModified || LongPath)); then
echo "$NbFileNOTModified fichiers , $NbRepNOTModified répertoires n ' ayant pas pu etre modifiés"
echo "vous avez $LongPath répertoires de taille trop importante."
echo "liste des erreurs : cat '$log_error'"
echo;
fiExiste il un moyen plus élégant / performant d ' établir la " recirculation " du dossier déplacé , plutôt que de faire :
if test -d "$nomOriginal"; then # si c' est un dossier
....
...
if test "$modif_activ" = true; then
mv -v "$nomOriginal" "$nomModif"
((NbRepModified++))
echo "$NbRepModified CREER_REP : mkdir '$nomModif'" >> "$log_modifs"
bash "$0" "$nomModif"
fi?
Dernière modification par iznobe (Le 29/04/2026, à 09:59)
Hors ligne