Résolu Problème de réorganisation et de renommage de dossiers et sous dossiers

Plus d'informations
il y a 3 ans 7 mois - il y a 3 ans 7 mois #29964 par Mathias
Bonjour

Je précise que je suis novice en PowerShell et que je n'y comprends pas grand chose...

Mon premier problème est j'imagine assez simple à résoudre pour un habitué du PowerShell. J'aimerais modifier cette arborescence :
dossier 'DP2'
- sous dossier 'tier 1'

-- sous sous dossier '1.1'
-- sous sous dossier '1.2'
-- sous sous dossier '1.3'
- sous dossier 'tier 2'
-- sous sous dossier '2.1'
-- sous sous dossier '2.2'
-- sous sous dossier '2.3'
- sous dossier 'tier 3'
-- sous sous dossier '3.1'
-- sous sous dossier '3.2'
-- sous sous dossier '3.3'


En cette arborescence :
dossier 'DP2'
- sous dossier '1.1'
- sous dossier '1.2'
- sous dossier '1.3'
- sous dossier '2.1'
- sous dossier '2.2'
- sous dossier '2.3'
- sous dossier '3.1'
- sous dossier '3.2'
- sous dossier '3.3'


Comment faire ?

Si vous voulez essayer par vous-même, vous trouverez les liens de téléchargements sur cette page : www.fretsonfire.org/forums/v...hp?f=5&t=49189 (il faut se créer un compte pour y accéder).
Vous n'avez pas besoin de tout télécharger, juste les fichiers 'tier 1', 'tier 2' et 'tier 3' devraient suffire pour des tests.
Si je veux automatiser ce travail, c'est parce que c'est trop galère à faire à la main car j'ai 22 dossiers 'tier n' dans le dossier DP3, 27 dans le DP4 et ainsi de suite. Ça doit être possible (et assez basique) de l'automatiser en PowerShell ... mais ce langage est vraiment du charabia pour moi et ça va me prendre trois jours pour peut-être y arriver, ou pas.


Mon deuxième problème est le suivant :
J'ai maintenant un dossier 'DP2' contenant des dizaines de sous dossiers dont les noms ont cette forme : 'préfixe inutile' + 'nom à garder'
Voici deux exemples de noms :
9.1 Rush - Anthem
9.2 Iron Maiden - El Dorado


J'aimerais modifier automatiquement tous ces noms de sous dossiers pour les transformer en : 'nom à garder'
Ça donnerait sur mes deux exemples :
Rush - Anthem
Iron Maiden - El Dorado


Pour ce faire, j'utilise cette ligne de commande :
dir | rename-item -NewName {$_.name.substring(4,$_.BaseName.length-4)}

Elle fonctionne parfaitement sur certains sous dossiers ou bugue complètement sur d'autres. Je n'arrive pas à comprendre pourquoi sur certains des sous dossiers (pas tous), la commande est exécutée 2 fois et je perds donc 4 caractères (de trop) que je voulais garder.
Le bugue donnerait sur mes deux exemples :
- Anthem
Maiden - El Dorado

Mais pourquoi donc ? Comment y remédier ?

Ensuite, J'aimerais ajouter un préfixe : 'préfixe utile' + 'nom à garder' = 'nouveau nom à garder'
Ça donnerait sur mes deux exemples :
DP2 Rush - Anthem
DP2 Iron Maiden - El Dorado


Pour ce faire, j'utilise cette ligne de commande :
dir | rename-item -NewName {"DP2 " + $_.name}

Comme précédemment, elle fonctionne parfaitement sur certains sous dossiers ou bugue complètement sur d'autres. Je n'arrive pas à comprendre pourquoi sur certains des sous dossiers (pas tous), la commande est exécutée 2,3, jusqu'à plus de 10 fois et je retrouve le préfixe ajouté plusieurs fois en conséquence.
Le bugue donnerait sur mes deux exemples :
DP2 DP2 DP2 Rush - Anthem
DP2 DP2 DP2 DP2 DP2 Iron Maiden - El Dorado

Mais pourquoi donc ? Comment y remédier ?

Pour rattraper le coup, je bidouille, j’utilise alors cette ligne de commande (qui ne bugue jamais jusqu'à présent) autant de fois que nécessaire pour supprimer les préfixes répétés :
dir | rename-item -NewName {$_.name -replace "DP2 DP2 ","DP2 "}
Ça va toujours plus vite que tout faire à la main...

Pour conclure :
- pour supprimer les 'préfixe inutile', je n'y arrive pas (Grrrrrrr)
- pour ajouter le 'préfixe utile', je contourne le problème en bidouillant.
J'ai l'impression que mon erreur est la source des deux problèmes mais je ne comprends pas où elle est.

On m'a suggéré d'utiliser un script avec un test et une condition basée sur une trame commune à tout les noms (Where-Object{$_.Name -match "^.\.. .*$"}) qui évite forcément un double passage :
Get-ChildItem | Where-Object {$_.PSIsContainer} | Where-Object{$_.Name -match "^.\.. .*$"} | Rename-Item -Path {$_.FullName} -NewName {$_.Name.substring(4, $_.Name.length-4)}
Ça fonctionne parfaitement mais ça ne me dit pas pourquoi ce que je faisais avant buguait.

Il me reste plus qu'à comprendre comment construire la condition pour l'adapter à d'autres configurations...
"^.\.. .*$" -> un premier caractère, suivi d'un point, suivi d'un caractère, suivi d'un espace
J'essaie de comprendre :
"^." = caractère ?
"\." = point ?
".." = caractère ? (pourquoi différent de "^.)
" ." = espace ?
"*$" = ???


Est-ce que quelqu'un peux me dire où je peux trouver les infos ou m'expliquer les bases de ce code de condition que je ne comprends pas ?
Même si je ne suis pas capable d'écrire un tel script, j'aimerais pouvoir construire moi-même mes conditions à partir de ce script pour l'adapter à un maximum de configurations.

Est-ce quelqu'un a des solutions. A l'aide !!!
Dernière édition: il y a 3 ans 7 mois par Mathias.

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 3 ans 7 mois - il y a 3 ans 7 mois #29967 par rhiwotar
Bonjour,

Pour ton problème de préfixe
$nom.Split("-") |select -last 1

ça permet de découper le nom de ton fichier à chaque "-" et de prendre seulement le dernier morceau du nom.

Pour ajouter un préfixe
$nom = $prefixe+$nom
devrait faire l'affaire

Je t'avouerai que j'ai pas chercher pour ton souci d'arborescence.



... Bon d'accord, je m'ennuie un peu et j'ai cherché
Get-ChildItem C:\Test\ -Directory -Recurse -Exclude (Get-ChildItem C:\Test)|Move-Item -Destination c:\test
tout les dossiers de l'arborescence, présent dans le répertoire auquel on exclu les dossiers à la racine sont déplacé dans le dossier racine.
Dernière édition: il y a 3 ans 7 mois par rhiwotar.
Les utilisateur(s) suivant ont remercié: Arnaud Petitjean

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 3 ans 7 mois - il y a 3 ans 7 mois #29970 par Arnaud Petitjean
Bonjour et bienvenue dans le forum de la communauté PowerShell !

Je précise que je suis novice en PowerShell et que je n'y comprends pas grand chose...


Au moins ça a le mérite d'être clair ! ;)
Je te conseille d'acheter le livre "PowerShell les fondamentaux" aux éditions ENI, écrit par votre humble serviteur . Un peu d'autopromo ne fait pas de mal :P


Il me reste plus qu'à comprendre comment construire la condition pour l'adapter à d'autres configurations...
"^.\.. .*$" -> un premier caractère, suivi d'un point, suivi d'un caractère, suivi d'un espace
J'essaie de comprendre :
"^." = caractère ?
"\." = point ?
".." = caractère ? (pourquoi différent de "^.)
" ." = espace ?
"*$" = ???

Est-ce que quelqu'un peux me dire où je peux trouver les infos ou m'expliquer les bases de ce code de condition que je ne comprends pas ?


Toute expression que tu testes avec l'opérateur Match est une expression régulière. Les expressions régulières représentent à elles seules un langage (qui peut être trèèèès complexe). Si tu n'y connais rien, tu as deux options : soit tu te formes (il y a des milliers de ressources sur internet), soit tu les mets de côté et tu utilises l'opérateur -Like et tu utilises le caractère étoile "*" qui se substitue à 0 ou n caractères et le caractère "?" qui se substitue à 0 ou 1 caractère.

Arnaud

MVP PowerShell et créateur de ce magnifique forum :-)
Auteur de 6 livres PowerShell aux éditions ENI
Fondateur de la société Start-Scripting
Besoin d'une formation PowerShell ?
Dernière édition: il y a 3 ans 7 mois par Arnaud Petitjean.

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 3 ans 7 mois - il y a 3 ans 7 mois #29975 par Mathias
J'avais posté mon problème sur 'developpez.net' (www.developpez.net/forums/d2088474/gener...ssiers/#post11604680) avant de le poster sous une formulation plus propre sur 'powershell-scripting.com'.
Un grand merci à 'ericlm128' qui m'a proposé les scripts qui solutionnent tous mes problèmes. J'aurais été bien incapable de m'en sortir tout seul.


Voici les 3 scripts que j'utiliserai à l'avenir :

Pour le déplacement de tous les fichiers et sous dossiers :
$dossier = "C:\Users\saih_tam\DP2"
(Get-ChildItem -Path "$dossier\*\*") | Move-Item -Destination {"$dossier\$($_.Name)"}


Pour la suppression des 'préfixes inutiles' :
$dossier = "C:\Users\saih_tam\DP2"
(Get-ChildItem -Path "$dossier\*") | Where-Object {$_.PSIsContainer} | Where-Object{$_.Name -match "^.\.. .*$"} | Rename-Item -Path {$_.FullName} -NewName {$_.Name.substring(4, $_.Name.length-4)}

Petites explications complémentaires :
$_.Name -match "^.\.. .*$" = On vérifie si une chaine de caractère (le nom ici) correspond à notre modèle de regexp (aussi appeler pattern)
"^" = début de la chaine
"." = un caractère
"\." = un point. Obliger de l’échapper avec \ sinon il serait considéré comme un caractère
"." = un caractère
" " = un espace
".*" = un caractère, 0 ou plusieurs fois
"$" = fin de la chaine

Pour construire le test qui se base sur des 'expressions régulières' aussi appelées 'regexp' ou 'regex'
Voici une aide : docs.microsoft.com/fr-fr/dotnet/standard...uage-quick-reference


Et enfin, pour l'ajout d'un 'préfixe utile' :
$dossier = "C:\Users\saih_tam\DP2"
(Get-ChildItem -Path "$dossier\*") | Where-Object {$_.PSIsContainer} | Rename-Item -Path {$_.FullName} -NewName {"DP2 " + $_.name}


Encore un immense merci à 'ericlm128' de 'developpez.net'.
Je passe le sujet en 'résolu'.
Dernière édition: il y a 3 ans 7 mois par Mathias.

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.080 secondes
Propulsé par Kunena