web-dev-qa-db-fra.com

Comment renommer en bloc des fichiers dans PowerShell?

J'essaie de faire ce qui suit:

Rename-Item c:\misc\*.xml *.tmp

Je veux fondamentalement changer l'extension sur tous les fichiers d'un répertoire en .tmp au lieu de .xml. Je n'arrive pas à trouver un moyen simple de faire cela dans PowerShell.

34
James Alexander

Dérivé de l'exemple 4 dans la documentation d'aide de Rename_Item, récupéré avec la commande:

get-help Rename-Item -examples

Exemple:

Get-ChildItem *.xml | Rename-Item -NewName { $_.Name -replace '\.xml','.tmp' }

Notez l'explication dans la documentation d'aide relative à la barre oblique inversée dans la commande replace, car elle utilise des expressions régulières pour rechercher le texte à remplacer.

48
dugas

Cela fonctionne bien aussi lorsque vous êtes dans le répertoire souhaité.

Dir | Rename-Item –NewName { $_.name –replace "old","new" }
16
etoxin

Les réponses existantes suggèrent l'opérateur -replace, mais que se passe-t-il si le fichier s'appelle a.xml.xml? Les deux chaînes .xml seront remplacées et le résultat final serait a.tmp.tmp. Heureusement, il existe une méthode .NET pour cela:

Dir *.xml | rename-item -newname { [io.path]::ChangeExtension($_.name, ".tmp") } 

( Manish Kumar était proche de GetFileNameWithoutExtension mais ceci est plus élégant et probablement un peu plus efficace, pas que cela compte trop dans ce cas)

8
Ohad Schneider

Voici une autre variante qui fonctionnera.

dir *.xml | Rename-Item -NewName {$_.BaseName + ".tmp"}

$_.BaseName fera le nom "base" sans la (dernière) extension.

2
Trashman

une version abrégée utilisant l'alias serait:

ls *.xml | ren -new {$_.BaseName + ".tmp"}
1
spinalfrontier
dir -Recurse | where-object -FilterScript {$_.Extension -eq ".xml"} | Rename-Item -NewName {[System.IO.Path]::GetFileNameWithoutExtension($_.fullname) + ".tmp"}

utilisez -WhatIf pour évaluer le résultat en premier

1
Manish Kumar

Encore plus facile - rappelez-vous que la chaîne de recherche de remplacement est une expression régulière,

dir *.xml | rename-item -newname {$_.name -replace "xml$","tmp"}

Le "$" représente la fin de chaîne, donc les caractères "xml" doivent être les trois derniers caractères du nom de fichier.

1
John Smith

Cela semble fonctionner et est une méthode Pythonic, c'est-à-dire simple est mieux que complexe ( https://www.python.org/dev/peps/pep-0020/ ) :

$files = Get-ChildItem -file -Filter *.xml;
  ForEach ($file in $files)
  {
  $n = $file.Basename
  Copy-Item -Path $file -Destination "$n.tmp"
  Remove-Item "$n.xml"
  }