使用Powershell替换目录名、文件名和文件内容中的字符串

使用Powershell替换目录名、文件名和文件内容中的字符串,powershell,Powershell,我在一个特定的目录和子目录中有数千个文件 C:\Food\ C:\Food\Avocado.sln(还包含字符串“Avocado”) C:\Food\Avocado.DataModel\ C:\Food\Avocado.DataModel\AvocadoModel.cs(还包含字符串“Avocado”) 我想在目录名称、文件名和文件内容中用“Burger”替换字符串“Avocado”的所有实例,例如 C:\Food\ C:\Food\Burger.sln(文件内容中“鳄梨”的所有内容现在改

我在一个特定的目录和子目录中有数千个文件

  • C:\Food\
  • C:\Food\Avocado.sln
    (还包含字符串“Avocado”)
  • C:\Food\Avocado.DataModel\
  • C:\Food\Avocado.DataModel\AvocadoModel.cs
    (还包含字符串“Avocado”)
我想在目录名称、文件名和文件内容中用“Burger”替换字符串“Avocado”的所有实例,例如

  • C:\Food\
  • C:\Food\Burger.sln
    (文件内容中“鳄梨”的所有内容现在改为“Burger”)
  • C:\Food\Burger.DataModel\
  • C:\Food\Burger.DataModel\BurgerModel.cs
    (文件内容中“鳄梨”的所有部分现在改为“Burger”)
我想使用Powershell来完成此操作


如何执行此操作?

我使用下面的脚本更改目录名、文件名和文件内容。我知道使用pipe
|
操作符可能会有更简单的方法来实现这一点,但目前这对我来说很有意义(我对Powershell比较陌生)

#更改这三个变量以满足您的需求
$baseDirectory=“C:\Food\”
$a=“鳄梨”
$b=“汉堡”
#获取所有文件
$files=Get ChildItem$baseDirectory-File-Recurse
#获取所有目录
$directorys=Get ChildItem$baseDirectory-Directory-Recurse
#仅当存在匹配项时才替换文件的内容
foreach($files中的文件)
{
$fileContent=获取内容-路径$file.FullName
如果($fileContent-匹配$a)
{
$newFileContent=$fileContent-替换$a、$b
设置内容-路径$file.FullName-值$newFileContent
}
}
#先更改文件名,然后更改目录名
#遍历文件并更改其名称
foreach($files中的文件)
{
如果($file-匹配$a)
{
$newName=$file.Name-替换$a、$b
重命名项-Path$file.FullName-NewName$NewName
}
}
#反转目录数组,这样我们就可以先执行最深的操作
#这会阻止我们重命名父目录,然后尝试重命名不再存在的子目录
#例如。
#我们可能有一个目录结构“C:\Rename\Rename”
#文件数组将是[C:\Rename,C:\Rename\Rename]
#在不反转的情况下,我们将第一个目录重命名为“C:\NewName”
#目录结构现在将是“C:\NewName\Rename”
#然后,我们尝试重命名C:\rename\rename,这将失败
[数组]::反向($directorys)
#遍历目录并更改其名称
foreach($directorys中的目录)
{
如果($directory-匹配$a)
{
$newName=$directory.Name-替换$a、$b
重命名项-Path$directory.FullName-NewName$NewName
}
}

我甚至不会尝试编辑可能的二进制文件,
因此,以下脚本仅处理指定的文件类型
为了安全起见,我们做了一个备份

$baseDirectory = "C:\Food\"
$a = "Avocado"
$b = "Burger"
$Include = '*.sln','*.cs'


Pushd $baseDirectory

# process all file and  directory names 
Get-ChildItem -Filter "*$a*" -Recurse|
  Rename-Item -NewName {$_.Name -replace $a,$b} -confirm


Get-ChildItem -Include $Include -Recurse | ForEach-Object{
  if (Select-String -Path $_ -Pattern $a -quiet){
    $BakName = "{0}.bak" -f $_.FullName
    $OldName = $_.FullName
    $_ | Move-Item -Destination $BakName -force
    (Get-Content $BakName) -replace $a,$b | Set-Content $OldName
  }
}
PopD

要检查的文件类型只有
.sln
.cs
?仅检查包含鳄梨或常规的文件夹中的文件?仅在文件名或全部中包含鳄梨内容时才检查文件?@LotPings所有文件。我正在学习如何使用powershell,所以将我的答案发布在下面。我相信还有其他(更好的)方法来实现我的目标。我还意识到,当我的目录包含二进制文件时,我的解决方案可能会出现问题(因此在我的情况下,我删除了
\bin
\obj
目录)