使用Powershell替换目录名称,文件名和文件内容中的字符串
问题描述:
我在特定目录和子目录中有数千个文件。使用Powershell替换目录名称,文件名和文件内容中的字符串
C:\Food\
-
C:\Food\Avocado.sln
(还包含字符串 “鳄梨”) C:\Food\Avocado.DataModel\
-
C:\Food\Avocado.DataModel\AvocadoModel.cs
(还包含字符串 “鳄梨”)
我想全部更换在目录名称中带有“Burger”的字符串“Avocado”的实例,文件名和文件内容例如
C:\Food\
-
C:\Food\Burger.sln
(所有intances “在文件内容鳄梨现改为 ”汉堡“) C:\Food\Burger.DataModel\
-
C:\Food\Burger.DataModel\BurgerModel.cs
(所有intances” 在文件内容鳄梨现改为 “汉堡” )
我想使用Powershell来做到这一点。
我该怎么做?
答
我用下面的脚本来改变目录名,文件名和文件内容。我知道可能有更简单的方法来使用管道运营商|
来做到这一点,但这对我来说很有意义(我对Powershell来说相对较新)。
# change these three variables to suit your requirements
$baseDirectory = "C:\Food\"
$a = "Avocado"
$b = "Burger"
# get all files
$files = Get-ChildItem $baseDirectory -File -Recurse
# get all the directories
$directorys = Get-ChildItem $baseDirectory -Directory -Recurse
# replace the contents of the files only if there is a match
foreach ($file in $files)
{
$fileContent = Get-Content -Path $file.FullName
if ($fileContent -match $a)
{
$newFileContent = $fileContent -replace $a, $b
Set-Content -Path $file.FullName -Value $newFileContent
}
}
# change the names of the files first then change the names of the directories
# iterate through the files and change their names
foreach ($file in $files)
{
if ($file -match $a)
{
$newName = $file.Name -replace $a, $b
Rename-Item -Path $file.FullName -NewName $newName
}
}
# reverse the array of directories so we go deepest first
# this stops us renaming a parent directory then trying to rename a sub directory which will no longer exist
# e.g.
# we might have a directory structure "C:\Rename\Rename"
# the file array would be [ C:\Rename, C:\Rename\Rename ]
# without reversing we'd rename the first directory to "C:\NewName"
# the directory structure would now be "C:\NewName\Rename"
# we'd then try to rename C:\Rename\Rename which would fail
[array]::Reverse($directorys)
# iterate through the directories and change their names
foreach ($directory in $directorys)
{
if ($directory -match $a)
{
$newName = $directory.Name -replace $a, $b
Rename-Item -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
@LotPings所有文件。我正在学习如何使用PowerShell,因此在下面发布了我的答案。我相信还有其他(更好的)方法可以实现我想要的。我也意识到,当我的目录conatins二进制文件时,我的解决方案可能存在问题(所以对于我的情况,我删除了\ bin和\ obj目录) –