2010-09-29 15 views
16

J'essaye de renommer un tas de fichiers récursivement en utilisant Powershell 2.0. La structure du répertoire ressemble à ceci:Renommer les fichiers en minuscules dans Powershell

Leaflets 
+ HTML 
    - File1 
    - File2 
    ... 
+ HTMLICONS 
    + IMAGES 
    - Image1 
    - Image2 
    - File1 
    - File2 
    ... 
+ RTF 
    - File1 
    - File2 
    ... 
+ SGML 
    - File1 
    - File2 
    ... 

J'utilise la commande suivante:

get-childitem Leaflets -recurse | rename -newname { $_.name.ToLower() } 

et il semble renommer les fichiers, mais se plaint des sous-répertoires:

Rename-Item : Source and destination path must be different. 

I recharger les données mensuellement en utilisant robocopy, mais les répertoires ne changent pas, donc je peux les renommer à la main. Est-il possible d'obtenir get-children pour ignorer les sous-répertoires (comme find Leaflets -type f ...)?

Merci.

MISE À JOUR: Il semble que le problème concerne les fichiers qui sont déjà tous en minuscules. J'ai essayé de changer la commande:

get-childitem Leaflets -recurse | if ($_.name -ne $_name.ToLower()) rename -newname { $_.name.ToLower() } 

mais maintenant Powershell se plaint que if n'est pas une applet de commande, fonction, etc. Puis-je redirigez la sortie de get-childitem à une déclaration if?

MISE À JOUR 2: Cela fonctionne:

$files=get-childitem Leaflets -recurse 
foreach ($file in $files) 
{ 
    if ($file.name -ne $file.name.ToLower()) 
    { 
     rename -newname { $_.name.ToLower() } 
    } 
} 

Répondre

20

Même si vous avez déjà posté votre propre réponse, voici une variante:

dir Leaflets -r | % { if ($_.Name -cne $_.Name.ToLower()) { ren $_.FullName $_.Name.ToLower() } } 

Quelques points:

  • dir est un alias pour Get-ChildItem (et -r est l'abréviation de -Recurse).
  • % est un alias pour ForEach-Object.
  • -cne est une comparaison sensible à la casse. -ne ignore les différences de casse.
  • $ _ est la manière dont vous référencez l'élément actuel dans la boucle ForEach-Object.
  • ren est un alias pour Rename-Item.
  • FullName est probablement préférable car il garantit que vous toucherez le bon fichier.

Si vous voulez exclut les répertoires d'être renommé, vous pouvez inclure quelque chose comme:

if ((! $_.IsPsContainer) -and $_.Name -cne $_.Name.ToLower()) { ... } 

Espérons que cela est utile pour continuer à apprendre et à explorer PowerShell.

10

Gardez à l'esprit que vous pouvez diriger directement Rename-Item et utiliser Scriptblocks avec le paramètre - NewName (car il accepte également l'entrée de pipeline) pour simplifier cette tâche:

Get-ChildItem -r | Where {!$_.PSIsContainer} | 
        Rename-Item -NewName {$_.FullName.ToLower()} 

et alias:

gci -r | ?{!$_.PSIsContainer} | rni -New {$_.FullName.ToLower()} 
+0

Merci. Et pour changer les noms de fichiers, nous pouvons utiliser ceci: gci. -recurse -force | ? {! $ _. PSIsContainer} | rni -New {$ _. Name.replace ("aaa", "bbb")} –

0

Il est plus idiomatiques dans PowerShell à utiliser where au lieu de if dans un pipeline:

 
gci -Recurse Leaflets | 
    ? { $_.Name -ne $_.Name.ToLower()) } | 
    % { ren -NewName $_.Name.ToLower() } 
1

légère tweak sur ce point, si vous ne souhaitez que mettre à jour les noms des fichiers d'un type particulier, essayez ceci:

get-childitem *.jpg | foreach { if ($_.Name -cne $_.Name.ToLower()) { ren $_.FullName $_.Name.ToLower() } } 

cela ne minuscule les fichiers jpg dans votre dossier et ignorer le reste

1

Vous devez les renommer temporairement en quelque chose d'autre, puis les renommer en minuscules.

$items = get-childitem -Directory -Recurse 

foreach ($item in $items) 
{ 

    if ($item.name -eq $item.name.ToLower()) 
    {  

     $temp = $item.FullName.ToLower() + "_" 
     $name = $item.FullName.ToLower() 
     ren $name $temp 

     ren $temp $name 
    }