2011-04-13 26 views
7

Con PowerShell (aunque otras sugerencias son bienvenidos), ¿cómo hace un bucle de forma recursiva un directorio/carpeta y¿Cómo reemplazar cadena en archivos y nombres de archivos y carpetas recursivamente con PowerShell?

  1. reemplazar texto A con B en todos los archivos,
  2. renombrar todos los archivos de forma que A se sustituye por B y, por último,
  3. ¿cambiar el nombre de todas las carpetas también para que A se reemplace por B?
+0

Así que quieres un comando/función que reemplace A con B en el contenido de los archivos, nombres de archivo y nombres de carpeta o son A y B por separado en cada uno de esos casos? –

+0

"es un comando/función que reemplazará A con B en el contenido del archivo, nombres de archivo y nombres de carpeta" es el caso. –

Respuesta

12

Con unos requisitos refinamientos, que terminó con este script:

$match = "MyAssembly" 
$replacement = Read-Host "Please enter a solution name" 

$files = Get-ChildItem $(get-location) -filter *MyAssembly* -Recurse 

$files | 
    Sort-Object -Descending -Property { $_.FullName } | 
    Rename-Item -newname { $_.name -replace $match, $replacement } -force 



$files = Get-ChildItem $(get-location) -include *.cs, *.csproj, *.sln -Recurse 

foreach($file in $files) 
{ 
    ((Get-Content $file.fullname) -creplace $match, $replacement) | set-content $file.fullname 
} 

read-host -prompt "Done! Press any key to close." 
+1

Esto es asombroso. Cuando las personas se den cuenta de lo que este script les permitirá hacer, obtendrán mucho más votos ascendentes ... gracias. –

+0

Tenía algunas carpetas y espacios de nombres en los archivos de código que me daban un nombre como NameSpace.TestConsole (carpeta) y lo mismo ocurre con algunos de mis espacios de nombres, este script creaba muchos archivos vacíos llamados nombres, así que de alguna forma también crea nuevos archivos. ¿Hay alguna forma de garantizar que solo reemplaza y no crea? – FRoZeN

0

no probado, pero debe darle un punto de partida:

$a = 'A'; 
$b = 'B'; 
$all = ls -recurse; 
$files = = $all | where{ !$_.PSIsContainer); 
$files | %{ 
    $c = ($_ | get-itemcontent -replace $a,$b); 
    $c | out-file $_; 
} 
$all | rename-item -newname ($_.Name -replace $a,$b); 
+1

Puedo decir que no se ha probado, no hay forma de que se ejecute. :) – JasonMArcher

0

No probado, puede ser que estoy más suerte ;-)

 
$hello = 'hello' 
$world = 'world' 

$files = ls -recurse | ? {-not $_.PSIsContainer} 

foearch ($file in $files) { 
    gc -path $file | % {$_ -replace $hello, $world} | Set-Content $file 
    ri -newname ($file.name -replace $hello, $world) 
} 

ls -recurse | ? {$_.PSIsContainer} | ri -newname ($_.name -replace $hello, $world) 

Para utilizar el mismo recursividad:

 
$hello = 'hello' 
$world = 'world' 

$everything = ls -recurse 

foearch ($thing in $everything) { 
    if ($thing.PSIsContainer -ne $true) { 
    gc -path $thing | % {$_ -replace $hello, $world} | Set-Content $thing 
    } 
    ri -newname ($thing.name -replace $hello, $world) 
} 
+0

Es un poco complejo, así que lo probaría como un script. –

3

Me gustaría ir con algo como esto:

Get-ChildItem $directory -Recurse | 
    Sort-Object -Descending -Property { $_.FullName } | 
    ForEach-Object { 
     if (!$_.PsIsContainer) { 
      ($_|Get-Content) -replace 'A', 'B' | Set-Content $_.FullName 
     } 
     $_ 
    } | 
    Rename-Item { $_.name -replace 'A', 'B' } 

El Sort-Object está allí para asegurar que los primeros hijos (subdirectorios, archivos) se enumeran y luego los directorios después de ellos. (12345)

+0

No funciona. –

+2

Y la pregunta es: ¿por qué? :) Como alguien 'alrededor de las computadoras', podrías saber que "No funciona" es tan valioso como si no digas nada. El mensaje de error es útil. De lo contrario, no es necesario decir "No funciona". :) – stej

0

Necesitaba esto por mí mismo y por debajo ligeramente mejor versión del guión.

que añade siguientes:

  1. Soporte para el parámetro detallado para que pueda ver realmente lo que cambia la escritura ha hecho.
  2. Posibilidad de especificar carpetas para que pueda limitar los cambios.
  3. Agregando bower.json, txt y md para incluir extensiones.
  4. Buscar y reemplazar contenido primero, renombrarlo más tarde.
  5. No reemplace el contenido si no se encuentra la cadena de búsqueda (esto evita cambios innecesarios en la fecha de modificación).
[CmdletBinding(SupportsShouldProcess=$true)] 
Param() 

$match = "MyProject" 
$replacement = Read-Host "Please enter project name" 

$searchFolders = @("MyProject.JS", "MyProject.WebApi", ".") 
$extensions = @("*.cs", "*.csproj", "*.sln", "bower.json", "*.txt", "*.md") 
foreach($searchFolderRelative in $searchFolders) 
{ 
    $searchFolder = join-path (get-location) $searchFolderRelative 
    Write-Verbose "Folder: $searchFolder" 

    $recurse = $searchFolderRelative -ne "." 

    if (test-path $searchFolder) 
    { 
     $files = Get-ChildItem (join-path $searchFolder "*") -file -include $extensions -Recurse:$recurse | 
        Where-Object {Select-String -Path $_.FullName $match -SimpleMatch -Quiet} 

     foreach($file in $files) 
     { 
      Write-Verbose "Replaced $match in $file" 
      ((Get-Content $file.fullname) -creplace $match, $replacement) | set-content $file.fullname 
     } 

     $files = Get-ChildItem $searchFolder -filter *$match* -Recurse:$recurse 

     $files | 
      Sort-Object -Descending -Property { $_.FullName } | 
      % { 
       Write-Verbose "Renamed $_" 
       $newName = $_.name -replace $match, $replacement 
       Rename-Item $_.FullName -newname $newName -force 
      }  
    } 
    else 
    { 
     Write-Warning "Path not found: $searchFolder" 
    } 
} 

Tenga en cuenta que un cambio de la respuesta es que por encima de la carpeta recursivamente sólo en carpetas especificadas, no en las raíces. Si no quiere eso, simplemente configure $recurse = true.

+0

@BrokenHeart ¿Algún motivo por el que desea [cambiar mi edición] (http://stackoverflow.com/posts/23103932/revisions)? – Antony

+0

@Antony No hay razón para hacerlo mucho mejor. –

0

Utilice Notepad ++ Si no tiene esta herramienta, se está perdiendo una gran cantidad de características necesarias para la manipulación de archivos.

Tiene una función de reemplazo que le permite buscar en un directorio determinado, proporcionar patrones para los archivos y reemplazarlos usando regexp, una función extendida o reemplazos normales.

Potente herramienta.

Es gratis: (http://notepad-plus-plus.org/download/v6.6.9.html)

Cuestiones relacionadas