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.
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.
Cela fonctionne bien aussi lorsque vous êtes dans le répertoire souhaité.
Dir | Rename-Item –NewName { $_.name –replace "old","new" }
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)
Voici une autre variante qui fonctionnera.
dir *.xml | Rename-Item -NewName {$_.BaseName + ".tmp"}
$_.BaseName
fera le nom "base" sans la (dernière) extension.
une version abrégée utilisant l'alias serait:
ls *.xml | ren -new {$_.BaseName + ".tmp"}
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
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.
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"
}