我的挑战:递归重{subf3}
命名根路径的第 3 个子文件夹及以后的 {subf4, 5, 6,...},以仅保留其原始文件夹名称的前 4 个字符。
e:\ {rootf} \ {subf1} \ {subf2}\ {subf3} \ {subf4} \ {subf5} \ ...
查看树,其中显示了脚本应如何处理子文件夹重命名(前) 和 (后) 已处理。
此外,我需要将根文件夹标记为“x”作为根文件夹位置的第一个字符“ \ {rootf}
”,即“ \xNew Folder\
”被省略(跳过),并且根本没有进行任何处理或重命名。
\long path1 (BEFORE)
├───long path1
│ └───long path
│ └───long path
│ └───long path
│ └───long path
│ └───long path
│ └───long path
│ └───long path
\long path1 (AFTER)
├───long path1
│ └───long path
│ └───long path
│ └───long
│ └───long
│ └───long
│ └───long
│ └───long
(SKIPPED) \xNew folder , has "x" as 1st character)
├───xNew folder
│ └───New folder
│ └───New folder
│ └───New folder
│ └───New folder
这是我想出的 PowerShell 逻辑,但它不起作用并出现错误。
$rootFolder = "E:\"
# Define a function to recursively rename subfolders
function Rename-Subfolders($folder) {
$subfolders = Get-ChildItem -Path $folder -Directory | Where-Object { $_.Name -notlike 'x*' }
foreach ($subfolder in $subfolders) {
$originalName = $subfolder.Name
# Rename only the 2nd subfolder and beyond
if ($subfolder.Parent.Parent) {
$newName = $originalName.Substring(0, 4)
# Display the original and new names before renaming
Write-Host "$($originalName) (BEFORE)"
Write-Host "└───$($newName) (AFTER)"
# Rename the subfolder
Rename-Item -Path $subfolder.FullName -NewName $newName
}
# Recursively process subfolders
Rename-Subfolders -folder $subfolder.FullName
}
}
# Start renaming subfolders from the root folder
Rename-Subfolders -folder $rootFolder
Rename-Subfolders -folder $rootFolder -depth 0
导致此错误:
long path (BEFORE)
└───long (AFTER)
Rename-Item : Access to the path 'E:\long path1 (AFTER)\long path' is denied.
At E:\renametest.ps1:19 char:13
+ Rename-Item -Path $subfolder.FullName -NewName $newName
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (E:\long path1 (AFTER)\long path:String) [Rename-Item], IOException
+ FullyQualifiedErrorId : RenameItemIOError,Microsoft.PowerShell.Commands.RenameItemCommand
答案1
使用深度和长度控制进行递归目录重命名
使用递归重命名时,Rename-Item
您需要首先从最后一个文件夹开始,重命名它,然后从那里向后重命名其父文件夹,直到达到最小文件路径深度。
这可能会给其他人一些想法,让他们编写一些更优化的东西,也许用更少的变量和一些重构,但这似乎正是你所描述的需要。
它不会重命名根级父文件夹或每个文件夹下的后续两个子文件夹。它还将省略根级文件夹,并将要省略的字符作为变量的值$NotLike
。
通过文件夹深度和完整路径长度进行控制(仅限表格列表详细信息)
$NotLike = "x";
$rootPath = "E:\";
$rootFolders = (Get-ChildItem -Path $rootPath -Directory | Where-Object {$_.Name -notlike "$NotLike*"}).FullName;
$rootFolders | ForEach-Object {
$subFolders = Get-ChildItem -Path $_ -Recurse -Directory;
$dCnt = 0;
$Output = @();
$subFolders | ForEach-Object {
$_ | Add-Member -NotePropertyName "Depth" -NotePropertyValue $dCnt;
If ($_.Depth -gt 1) {$Output += $_};
$dCnt++
};
$Output | Sort-Object @{E={$_.FullName.Length}} -Descending | Select Depth, @{N="Length";E={$_.FullName.Length}}, FullName
};
输出
Depth Length FullName
----- ------ --------
6 90 E:\Long Path1\Long pathA\Long PathB\Long PathC\Long PathD\Long PathE\Long PathF\Long PathG
5 79 E:\Long Path1\Long pathA\Long PathB\Long PathC\Long PathD\Long PathE\Long PathF
4 68 E:\Long Path1\Long pathA\Long PathB\Long PathC\Long PathD\Long PathE
3 57 E:\Long Path1\Long pathA\Long PathB\Long PathC\Long PathD
2 46 E:\Long Path1\Long pathA\Long PathB\Long PathC
PowerShell(重命名操作)
$NotLike = "x";
$rootPath = "E:\";
$rootFolders = (Get-ChildItem -Path $rootPath -Directory | Where-Object {$_.Name -notlike "$NotLike*"}).FullName;
$rootFolders | ForEach-Object {
$subFolders = Get-ChildItem -Path $_ -Recurse -Directory;
$dCnt = 0;
$Output = @();
$subFolders | ForEach-Object {
$_ | Add-Member -NotePropertyName "Depth" -NotePropertyValue $dCnt;
If ($_.Depth -gt 1) {$Output += $_};
$dCnt++
};
$Output | Sort-Object @{E={$_.FullName.Length}} -Descending | ForEach-Object {
If ($_."Depth" -gt 1) {$_ | Rename-Item -NewName $_.Name.Substring(0, 4) -Force}}
};
前樹
E:\
├───Long Path1
│ └───Long pathA
│ └───Long PathB
│ └───Long PathC
│ └───Long PathD
│ └───Long PathE
│ └───Long PathF
│ └───Long PathG
└───xLong Path1
└───Long pathA
└───Long PathB
└───Long PathC
└───Long PathD
└───Long PathE
└───Long PathF
└───Long PathG
树后
E:\
├───Long Path1
│ └───Long pathA
│ └───Long PathB
│ └───Long
│ └───Long
│ └───Long
│ └───Long
│ └───Long
└───xLong Path1
└───Long pathA
└───Long PathB
└───Long PathC
└───Long PathD
└───Long PathE
└───Long PathF
└───Long PathG
支持资源
答案2
这个脚本完全符合我的要求,甚至超出了我的预期。我未来可能做的唯一更改是删除包含 1 个字符的子文件夹。目前这已经足够好了,我没有时间深入研究移动操作冲突期间的错误处理、日志记录和其他问题。
重命名脚本
$rootPath = "E:\";
$rootFolders = (Get-ChildItem -Path $rootPath -Directory | Where-Object {$_.Name -notlike "$NotLike*"}).FullName;
$rootFolders | ForEach-Object {
$subFolders = (Get-ChildItem -Path $_ -Recurse -Directory);
$Output = @();
$lastskipped = 0
$lastskippedct = 0;
$subFolders | ForEach-Object {
$dpth = $_.FullName.Split("\").Count -1;
$childFolderCount = (Get-ChildItem -Path $_.FullName -Directory).Count;
if ($_.FullName -like "$lastSkipped*") {
return;
};
$lastskipped = 0;
$lastskippedct = 0;
$_ | Add-Member -NotePropertyName "Depth" -NotePropertyValue $dpth;
$_ | Add-Member -NotePropertyName "CFldrCT" -NotePropertyValue $childFolderCount;
if ($dpth -ge 4 -and $childFolderCount -gt 1) {
$lastskipped = $_.FullName;
$lastskippedct++
if ($lastSkippedct -eq 1) {
$Output += $_;
};
return;
} elseif ($dpth -ge 4 -and $childFolderCount -le 1) {
$Output += $_;
};
};
$Output | Sort-Object @{E={$_.Depth}} -Descending | ForEach-Object {
if ($_.Name -ne $_.Name.Substring(0, 1)) {
$_ | Rename-Item -NewName ($_.Name.Substring(0, 1)) -Force
};
};
};
前
├───Beta
│ ├───expert expert exp
│ │ └───expert expert expert expert expert expert2
│ │ └───expert expert expert expert expert expert
│ │ └───expert expert expert expert expert expert
│ │ ├───fundamentals fundamentals
│ │ └───zero 2 hero zero 2 herozero 2 herozero 2 hero
│ ├───fundamentals fundamentals
│ │ └───fundamentals fundamentals4
│ │ └───fundamentals fundamentals
│ │ └───fundamentals fundamentals
│ │ └───fundamentals fundamentals
│ │ └───fundamentals fundamentals
│ │ ├───expert expert expert expert expert expert
│ │ ├───fundamentals fundamentals
│ │ └───zero 2 hero zero 2 herozero 2 herozero 2 hero
│ │ ├───New folder2
│ │ ├───New folder3
│ │ └───New folder4
│ └───zero 2 hero zero 2 her
│ └───zero2herozero2herozero2herozero2hero2
│ └───zero2herozero2herozero2herozero2hero
│ └───zero2herozero2herozero2herozero2hero
│ ├───fundamentals fundamentals
│ │ └───fundamentals fundamentals
│ │ ├───New folder
│ │ ├───New folder2
│ │ ├───New folder3
│ │ └───New folder4
│ └───zero2herozero2herozero2herozero2hero
后
├───Beta
│ ├───expert expert exp
│ │ └───expert expert expert expert expert expert2
│ │ └───e
│ │ └───e
│ │ ├───fundamentals fundamentals
│ │ └───zero 2 hero zero 2 herozero 2 herozero 2 hero
│ ├───fundamentals fundamentals
│ │ └───fundamentals fundamentals4
│ │ └───f
│ │ └───f
│ │ └───f
│ │ └───f
│ │ ├───expert expert expert expert expert expert
│ │ ├───fundamentals fundamentals
│ │ └───zero 2 hero zero 2 herozero 2 herozero 2 hero
│ │ ├───New folder2
│ │ ├───New folder3
│ │ └───New folder4
│ └───zero 2 hero zero 2 her
│ └───zero2herozero2herozero2herozero2hero2
│ └───z
│ └───z
│ ├───fundamentals fundamentals
│ │ └───fundamentals fundamentals
│ │ ├───New folder
│ │ ├───New folder2
│ │ ├───New folder3
│ │ └───New folder4
│ └───zero2herozero2herozero2herozero2hero