Changement de nom de lot dans PowerShell

J’essaie de mettre à jour un tas d’images .jpg afin qu’elles soient actualisées sur mon site Web. Ils sont actuellement stockés sur mon PC comme ceci:

  médias
 + - projet aléatoire
 |  + - 1.jpg
 |  + - 2.jpg
 |  + - 3.jpg
 |  `- thumb.png
 + - un autre projet aléatoire
 |  + - 1.jpg
 |  `- thumb.png 

J’essaie de renommer par lots tous les 1.jpg, 2.jpg etc. en 1a.jpg, 2a.jpg .

Je pense utiliser Windows PowerShell et quelque chose comme

 Get-ChildItem -Recurse -Filter "[0-9]+.jpg" | foreach { $_.FullName} Dir *.jpg | Rename-Item -NewName { $_.Name -replace "[0-9]+.jpg","[0-9]a.jpg" } 

mais n’ont jamais utilisé le programme avant. Qu’est-ce que tu penses?

  • Il est toujours utile d’utiliser le paramètre -Filter , s’il est disponible: il effectue un filtrage à la source et est donc généralement beaucoup plus rapide que le filtrage ultérieur .

  • La syntaxe de la valeur (chaîne) acceptée par le paramètre -Filter est cmdlet – / PowerShell drive-specific .
    Dans le cas de Get-ChildItem (et de son répertoire d’alias intégré et, dans Windows PowerShell, ls ), il accepte une seule expression génériquesimilaire aux expressions génériques de PowerShell – mais dont la syntaxe est dépendante de la plate-forme :

    • Sous Windows , l’expression ne peut contenir que * et ? wildcards – voir cette réponse .

    • Dans PowerShell Core sur les plates-formes Unix , l’expression peut également contenir des jeux de caractères tels que [0-9] .

[0-9]+.jpg ne fonctionne pas comme une valeur de -Filter , car il s’agit d’une expression régulière (expression régulière) .

En réserve: vous avez probablement eu l’intention d’utiliser . comme un littéral , auquel cas vous devriez y échapper dans le regex en tant que \. parce que est un métacaractère d’ expression régulière représentant n’importe quel caractère . dans l’entrée.

Vous ne pouvez pas émuler une expression régulière [0-9]+.jpg avec une expression générique, car même lorsque des expressions génériques prennent en charge des jeux de caractères tels que [0-9] , elles ne contiennent pas de symboles de duplication de sous-expression (quantificateurs) ? .
(En revanche, les métacaractères génériques * / ? Sont des constructions autonomes qui représentent une séquence de caractères éventuellement vide / exactement un caractère ).


Remarque: -WhatIf a été ajouté aux appels Rename-Item ci-dessous pour prévisualiser les modifications qui seraient apscopes.
Supprimez -WhatIf pour effectuer le renommage réel.

[ PowerShell Core sous Unix uniquement ] Si tous les fichiers *.jpg d’intérêt ont un nom de base (racine du nom de fichier) limité à un nombre à un chiffre (par exemple, 1.jpg , …, 9.jpg ), vous peut sortir avec passer une expression générique [0-9].jpg à -Filter :

 Get-ChildItem -File -Recurse -Filter [0-9].jpg | Rename-Item -NewName { $_.BaseName + 'a' + $_.Extension } -WhatIf 

Notez comment le passage de l’argument { $_.BaseName + 'a' + $_.Extension } au paramètre -NewName construit le nouveau nom de fichier à partir du nom de base du fichier d’entrée, suivi du littéral a , suivi de l’extension du fichier d’entrée.


Sinon ,

  • utiliser une expression générique *.jpg pour un pré- filtrage efficace ,

  • puis restreindre les résultats pré-filtrés aux correspondances spécifiques à regex avec un appel Where-Object qui utilise -match pour comparer le nom de base de chaque fichier d’entrée à regex ^[0-9]+$ , c.-à-d. composé de chiffres décimaux.

Remarque:
* La commande ci-dessous utilise la syntaxe PSv3 + Get-ChildItem et Where-Object .
* La regex transmise à -match utilise le -match simple ( '...' ) plutôt que le guillemet double ( "..." ) pour garantir que l’interpolation de chaîne de PowerShell ne gêne pas.

 Get-ChildItem -File -Recurse -Filter *.jpg | Where-Object BaseName -match '^[0-9]+$' | Rename-Item -NewName { $_.BaseName + 'a' + $_.Extension } -WhatIf 

Gci et Dir ou ls sont tous des alias de Get-ChildItem .
Ils n’utilisent que les caractères génériques dans l’option de filtre, pas les expressions régulières.
Pour n’inclure que les noms de base composés uniquement de nombres, vous pouvez:

 Get-ChildItem -Recurse -Filter "*.jpg" | Where-Object BaseName -match "^[0-9]+$"| Rename-Item -NewName { $_.Name -replace '([0-9]+)\.jpg','$1a.jpg'} -whatif 

Si la sortie semble correcte, supprimez le -whatif in the last line.

essaye ça

 Get-ChildItem "c:\temp" -recurse -file -Filter "*.jpg" | where Basename -match "^\d$" | Rename-Item -NewName {$("{0}{1}" -f $_.basename, "a.jpg")}