问题描述
|
使用PowerShell(尽管欢迎其他建议),如何递归地循环目录/文件夹以及
在所有文件中用B替换文本A,
重命名所有文件,以便将A替换为B,最后
还重命名所有文件夹,以便将A替换为B?
解决方法
经过一些需求改进,最终得到了以下脚本:
$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.\"
,我会选择这样的东西:
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\' }
ѭ2用来确保列出第一个子项(子目录,文件),然后列出其后的目录。 (12345)
,未经测试,但应该给您一个起点:
$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 );
,未经测试,也许我更幸运;-)
$ hello = \'hello \'
$ world = \'世界\'
$ files = ls -recurse | ? {-不是$ _。PSIsContainer}
foearch($ files中的$ file){
gc -path $ file | %{$ _ -replace $ hello,$ world} |设置内容$ file
ri -newname($ file.name -replace $ hello,$ world)
}
ls -recurse | ? {$ _。PSIsContainer} | ri -newname($ _。name -replace $ hello,$ world)
要使用相同的递归:
$ hello = \'hello \'
$ world = \'世界\'
$ everything = ls -recurse
foearch($ thing in $ everything){
如果($ thing.PSIsContainer -ne $ true){
gc -path $ thing | %{$ _ -replace $ hello,$ world} |设置内容$ thing
}
ri -newname($ thing.name -replace $ hello,$ world)
}
,我自己需要这个,下面是脚本的更好版本。
我添加了以下内容:
支持详细参数,因此您实际上可以查看脚本进行了哪些更改。
能够指定文件夹,以便您可以限制更改。
添加bower.json,txt和md以包括扩展名。
首先搜索和替换内容,然后再重命名。
如果找不到搜索字符串,请不要替换内容(这样可以避免不必要地更改修改日期)。
[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\"
}
}
请注意,答案的一个变化是,上述递归仅在指定文件夹中递归文件夹,而不在根目录中递归。如果您不想这样做,只需设置$recurse = true
。