2010-09-29 45 views
16

Estoy tratando de cambiar el nombre de un grupo de archivos de forma recursiva con Powershell 2.0. La estructura de directorios es el siguiente:Cambiar el nombre de los archivos a minúsculas en Powershell

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

estoy usando el siguiente comando:

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

y parece que cambiar el nombre de los archivos, pero se queja de los subdirectorios:

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

I recarga los datos mensualmente usando robocopy, pero los directorios no cambian, así que puedo cambiarles el nombre a mano. ¿Hay alguna forma de obtener get-children para omitir los subdirectorios (como find Leaflets -type f ...)?

Gracias.

ACTUALIZACIÓN: Parece que el problema está en los archivos que ya están en minúsculas. He intentado cambiar el comando para:

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

pero ahora se queja de que Powershell if no es un cmdlet, función, etc. ¿Puedo canalizar la salida de get-childitem un comunicado if?

ACTUALIZACIÓN 2: Esto funciona:

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

Respuesta

20

A pesar de que ya ha publicado su propia respuesta, aquí hay una variación:

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

Algunos puntos:

  • dir es un alias para Get-ChildItem (y -r es la abreviatura de -Recurse).
  • % es un alias de ForEach-Object.
  • -cne es una comparación entre mayúsculas y minúsculas. -ne ignora las diferencias de mayúsculas y minúsculas.
  • $ _ es cómo hace referencia al elemento actual en el bucle ForEach-Object.
  • ren es un alias de Rename-Item.
  • FullName es probablemente preferible, ya que garantiza que tocará el archivo correcto.

Si quería excluye directorios su cambio de nombre, que podría incluir algo como:

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

Esperemos que esto es útil para seguir aprendiendo y explorar PowerShell.

10

Tenga en cuenta que puede canalizar directamente a Renombrar-punto y utilizar Scriptblocks con el - NewName parámetro (ya que también acepta entradas de canalización) para simplificar esta tarea:

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

y con los alias:

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

Gracias. Y para cambiar los nombres de los archivos podemos usar esto: gci. -recurse -force | ? {! $ _. PSIsContainer} | rni -New {$ _. Name.replace ("aaa", "bbb")} –

0

Es más idiomáticas en PowerShell para usar en lugar de whereif en una tubería:

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

ligera inclinación en esto, si sólo desea actualizar los nombres de los archivos de un tipo particular, intente lo siguiente:

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

esto sólo minúsculas los archivos jpg dentro de su carpeta e ignorar el resto

1

Necesita cambiarles el nombre temporalmente a algo diferente y luego nombrarlos en minúsculas.

$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 
    } 
Cuestiones relacionadas