删除包含关键字,比如包含关键字"Artwork"的文件夹,文件中的内容移动到上一级?有相同名字的文件自动覆盖
# ===============================================
# 删除包含指定关键字的文件夹并将内容上移(同名文件自动覆盖)
# 完全支持路径中的中文、空格、特殊符号(如 &、()、#、! 等)
# 使用方法:
# 1. 用记事本打开此脚本,修改下面的 【需要修改】 部分
# 2. 保存为 .ps1 文件(如 flatten_folders.ps1)
# 3. 右键以管理员身份运行 PowerShell,执行该脚本
# ===============================================
# 【需要修改】在这里输入你的目标文件夹路径
# 必须用双引号包围整个路径,尤其是路径中含有空格、中文、特殊符号时
# 示例:
# $TargetPath = "D:\我的音乐\周杰伦 专辑合集"
# $TargetPath = "E:\Downloads\Music (2024)\Various Artists #1"
# $TargetPath = "F:\资源\歌手&乐团\Various\Artwork & Scans"
$TargetPath = "D:\你的目标文件夹" # ← 修改这里!请务必用双引号包围
# 【需要修改】在这里输入要匹配的关键字(区分大小写取决于下面的设置)
# 如果要匹配多个关键字,用 | 分隔,例如 "Artwork|Cover|Scans|Booklet"
$Keyword = "Artwork" # ← 修改这里!例如 "Cover" 或 "Scans|Booklet"
# 【可选修改】是否严格区分大小写
# $true = 区分大小写,$false = 不区分大小写(推荐 $false)
$CaseSensitive = $false # ← 如需区分大小写改为 $true
# ===============================================
# 以下部分无需修改
# ===============================================
# 检查路径是否存在
if (-not (Test-Path -LiteralPath $TargetPath -PathType Container)) {
Write-Error "错误:指定的路径不存在或不是文件夹!请检查路径是否正确:`n$TargetPath"
pause
exit
}
# 使用 -LiteralPath 以安全处理包含特殊字符的路径
Set-Location -LiteralPath $TargetPath
Write-Host "已成功进入目标文件夹:$TargetPath`n" -ForegroundColor Green
# 根据大小写设置构建匹配表达式
if ($CaseSensitive) {
$MatchPattern = $Keyword
} else {
$MatchPattern = $Keyword.ToLower()
}
# 获取所有子文件夹(递归),并安全处理名称中的特殊字符
Get-ChildItem -LiteralPath $TargetPath -Directory -Recurse | ForEach-Object {
$folderName = if ($CaseSensitive) { $_.Name } else { $_.Name.ToLower() }
if ($folderName -match $MatchPattern) {
$folder = $_.FullName
$parent = $_.Parent.FullName
Write-Host "发现匹配文件夹:$folder" -ForegroundColor Yellow
# 移动所有文件到父目录(-Force 自动覆盖同名文件)
# 使用 -LiteralPath 确保文件名含特殊字符时也正常处理
Get-ChildItem -LiteralPath $folder -File | ForEach-Object {
$dest = Join-Path $parent $_.Name
Move-Item -LiteralPath $_.FullName -Destination $dest -Force
Write-Host " 已移动并覆盖:$($_.Name)" -ForegroundColor Gray
}
# 删除空文件夹(支持嵌套)
try {
Remove-Item -LiteralPath $folder -Recurse -Force -ErrorAction Stop
Write-Host " 已删除文件夹:$folder`n" -ForegroundColor Green
} catch {
Write-Host " 删除失败(可能仍有内容或权限问题):$folder`n" -ForegroundColor Red
}
}
}
Write-Host "`n全部处理完成!" -ForegroundColor Green
# 暂停以便查看结果
pause
删除目录中的所有递归文件夹,所有递归文件移动到本目录中,注意要处理中文、空格、特殊符号
下面是完整 PowerShell 脚本,功能如下:
- 将指定目标目录下所有子文件夹(递归)中的文件全部移动到目标目录本身(本目录)
- 同名文件自动覆盖
- 处理完成后删除所有子文件夹(包括多层嵌套的空文件夹)
- 完全支持路径和文件名中包含中文、空格、特殊符号(如 &、()、#、! 等)
# ===============================================
# 将所有子文件夹中的文件递归移动到本目录,并删除所有子文件夹
# 完全支持中文、空格、特殊符号路径
# 使用方法:
# 1. 用记事本打开此脚本,修改下面的 【需要修改】 部分
# 2. 保存为 .ps1 文件(如 flatten_all.ps1)
# 3. 右键以管理员身份运行 PowerShell,执行该脚本
# ===============================================
# 【需要修改】在这里输入你的目标文件夹路径
# 必须用双引号完整包围整个路径(尤其是包含空格、中文、特殊符号时)
# 示例:
# $TargetPath = "D:\我的音乐\周杰伦 & 群星 (精选)"
# $TargetPath = "E:\Downloads\Various Artists #1\Temp Folder"
$TargetPath = "D:\你的目标文件夹" # ← 修改这里!
# ===============================================
# 以下部分无需修改
# ===============================================
# 检查路径是否存在
if (-not (Test-Path -LiteralPath $TargetPath -PathType Container)) {
Write-Error "错误:指定的路径不存在或不是文件夹!请检查路径是否正确:`n$TargetPath"
pause
exit
}
# 使用 -LiteralPath 安全处理特殊字符路径
Set-Location -LiteralPath $TargetPath
Write-Host "已进入目标文件夹:$TargetPath`n" -ForegroundColor Green
Write-Host "正在将所有子文件夹中的文件移动到本目录(同名文件将覆盖)..." -ForegroundColor Yellow
# 递归查找所有子文件夹中的文件(不包括本目录本身的文件)
Get-ChildItem -LiteralPath $TargetPath -File -Recurse | ForEach-Object {
$sourceFile = $_.FullName
$destFile = Join-Path $TargetPath $_.Name
Move-Item -LiteralPath $sourceFile -Destination $destFile -Force
Write-Host " 已移动并覆盖:$($_.Name) ← 来自 $($_.DirectoryName)" -ForegroundColor Gray
}
Write-Host "`n所有文件已移动完成!`n正在删除所有子文件夹..." -ForegroundColor Yellow
# 删除所有子文件夹(包括多层嵌套的空文件夹)
Get-ChildItem -LiteralPath $TargetPath -Directory -Recurse | Sort-Object FullName -Descending | ForEach-Object {
try {
Remove-Item -LiteralPath $_.FullName -Recurse -Force -ErrorAction Stop
Write-Host " 已删除文件夹:$($_.FullName)" -ForegroundColor Green
} catch {
Write-Host " 删除失败(可能仍有内容或权限问题):$($_.FullName)" -ForegroundColor Red
}
}
# 如果有残留的空文件夹,再尝试一次清理(保险起见)
Get-ChildItem -LiteralPath $TargetPath -Directory | ForEach-Object {
try {
Remove-Item -LiteralPath $_.FullName -Recurse -Force -ErrorAction Stop
Write-Host " [二次清理] 已删除残留空文件夹:$($_.FullName)" -ForegroundColor Green
} catch {}
}
Write-Host "`n全部处理完成!所有文件已扁平化到本目录,子文件夹已全部删除。" -ForegroundColor Green
# 暂停以便查看结果
pause
使用方法
-
新建文本文件,复制以上全部内容粘贴。
-
只修改一行:
$TargetPath = "你的实际路径" # 用双引号完整包围
可以指定层级吗?注意要处理中文、空格、特殊符号
下面是升级版 PowerShell 脚本,新增了指定处理层级(深度)的功能,同时继续完全支持路径和文件名中的中文、空格、特殊符号。新增功能
- $MaxDepth:控制最大处理深度(层级)
- 1 = 只处理目标目录下的一级子文件夹(不递归更深层)
- 2 = 处理一级 + 二级子文件夹
- 0 或负数 = 无限制(递归处理所有层级,默认行为)
- 文件全部移动到目标目录本级,同名自动覆盖
- 处理完成后删除所有涉及到的子文件夹
# ===============================================
# 将指定层级内的子文件夹文件递归移动到本目录,并删除这些子文件夹
# 支持指定最大深度,完全支持中文、空格、特殊符号路径
# 使用方法:
# 1. 用记事本打开此脚本,修改下面的 【需要修改】 部分
# 2. 保存为 .ps1 文件(如 flatten_by_depth.ps1)
# 3. 右键以管理员身份运行 PowerShell,执行该脚本
# ===============================================
# 【需要修改】目标文件夹路径(必须用双引号完整包围)
# 示例:
# $TargetPath = "D:\我的音乐\周杰伦 & 群星 (精选)"
# $TargetPath = "E:\Downloads\Various Artists #1\Temp Folder"
$TargetPath = "D:\你的目标文件夹" # ← 修改这里!
# 【需要修改】最大处理深度(层级)
# 1 = 只处理一级子文件夹
# 2 = 处理一级 + 二级子文件夹
# ...
# 0 或负数 = 无限制(处理所有层级)
$MaxDepth = 0 # ← 修改这里!例如 1(只扁平化一级)、2、或 0(全部)
# ===============================================
# 以下部分无需修改
# ===============================================
# 检查路径是否存在
if (-not (Test-Path -LiteralPath $TargetPath -PathType Container)) {
Write-Error "错误:指定的路径不存在或不是文件夹!请检查路径是否正确:`n$TargetPath"
pause
exit
}
# 规范化深度(0 或负数视为无限制)
if ($MaxDepth -le 0) {
$MaxDepth = [int]::MaxValue # 实际视为无限深度
}
Set-Location -LiteralPath $TargetPath
Write-Host "已进入目标文件夹:$TargetPath" -ForegroundColor Green
Write-Host "最大处理深度:$(if ($MaxDepth -eq [int]::MaxValue) { '无限制(所有层级)' } else { $MaxDepth })`n" -ForegroundColor Green
Write-Host "正在移动文件到本目录(同名文件将覆盖)..." -ForegroundColor Yellow
# 递归获取文件,但限制深度
Get-ChildItem -LiteralPath $TargetPath -File -Recurse | ForEach-Object {
# 计算当前文件相对于目标目录的深度
$relativePath = $_.FullName.Substring($TargetPath.Length).TrimStart('\')
$currentDepth = ($relativePath -split '\\').Count - 1 # 文件所在文件夹的深度
if ($currentDepth -le $MaxDepth) {
$destFile = Join-Path $TargetPath $_.Name
Move-Item -LiteralPath $_.FullName -Destination $destFile -Force
Write-Host " 已移动并覆盖:$($_.Name) ← 来自 $($_.DirectoryName)" -ForegroundColor Gray
}
}
Write-Host "`n文件移动完成!`n正在删除指定深度内的子文件夹..." -ForegroundColor Yellow
# 删除指定深度内的所有子文件夹(从最深层开始删除,避免中间层残留)
$foldersToDelete = Get-ChildItem -LiteralPath $TargetPath -Directory -Recurse | Where-Object {
$relativePath = $_.FullName.Substring($TargetPath.Length).TrimStart('\')
$depth = ($relativePath -split '\\').Count
$depth -le $MaxDepth
}
$foldersToDelete | Sort-Object FullName -Descending | ForEach-Object {
try {
Remove-Item -LiteralPath $_.FullName -Recurse -Force -ErrorAction Stop
Write-Host " 已删除文件夹:$($_.FullName)" -ForegroundColor Green
} catch {
Write-Host " 删除失败(可能仍有内容或权限问题):$($_.FullName)" -ForegroundColor Red
}
}
# 二次清理本级残留空文件夹(保险)
Get-ChildItem -LiteralPath $TargetPath -Directory | ForEach-Object {
try {
Remove-Item -LiteralPath $_.FullName -Recurse -Force -ErrorAction Stop
Write-Host " [二次清理] 已删除残留空文件夹:$($_.FullName)" -ForegroundColor Green
} catch {}
}
Write-Host "`n全部处理完成!指定层级的文件已扁平化到本目录,子文件夹已删除。" -ForegroundColor Green
# 暂停查看结果
pause
使用示例
| 你想实现的效果 | $MaxDepth 设置为 |
|---|---|
| 只处理一级子文件夹(最常见) | 1 |
| 处理一级 + 二级子文件夹 | 2 |
| 处理前三级 | 3 |
| 处理所有层级(不限深度) | 0 |
所有递归子文件夹,指定从某层开始所有递归的文件移动到某层。同名的自动改名。删除空文件夹。注意要处理中文、空格、特殊符号
- $StartDepth = 3
- $TargetDepth = 2
- 效果:第3层及更深层的所有文件 → 移动到它们各自所属的第2层目录中
- 同名文件自动改名(如 photo.jpg → photo (1).jpg)
- 处理完成后删除所有变空的文件夹(包括第3层及更深层)
- 完全支持中文、空格、&、()、# 等特殊符号路径和文件名
# ===============================================
# 修正版:从指定层级开始,将文件统一移动到指定的上一层级目录
# 同名自动改名 + 删除所有变空的文件夹
# 完全支持中文、空格、特殊符号路径
# ===============================================
# 【需要修改】目标文件夹路径(必须用双引号完整包围)
$TargetPath = "D:\你的目标文件夹" # ← 修改这里!例如 "F:\音乐\周杰伦 & 群星 (精选)#2024"
# 【需要修改】从第几层开始收集文件(包含该层及更深层)
# 例如 3 = 只收集第3层及更深层的文件
$StartDepth = 3 # ← 修改这里!
# 【需要修改】文件最终移动到第几层目录
# 例如 2 = 移动到各自所属的第2层目录
# 1 = 移动到最外层(根目录)
$TargetDepth = 2 # ← 修改这里!
# ===============================================
# 以下部分无需修改
# ===============================================
if (-not (Test-Path -LiteralPath $TargetPath -PathType Container)) {
Write-Error "错误:指定的路径不存在或不是文件夹!`n$TargetPath"
pause
exit
}
# 验证深度逻辑
if ($TargetDepth -ge $StartDepth) {
Write-Error "错误:TargetDepth 不能大于或等于 StartDepth!否则无意义。"
pause
exit
}
Set-Location -LiteralPath $TargetPath
Write-Host "已进入目标文件夹:$TargetPath" -ForegroundColor Green
Write-Host "从第 $StartDepth 层及以下的文件 → 移动到各自所属的第 $TargetDepth 层目录(同名自动改名)`n" -ForegroundColor Green
Write-Host "正在处理文件移动..." -ForegroundColor Yellow
# 获取所有文件并处理
Get-ChildItem -LiteralPath $TargetPath -File -Recurse | ForEach-Object {
$fullPath = $_.FullName
$relativePath = $fullPath.Substring($TargetPath.Length).TrimStart('\')
$parts = $relativePath -split '\\'
$depth = $parts.Count - 1 # 文件所在目录的深度
if ($depth -ge $StartDepth) {
# 取前 TargetDepth 层作为目标目录
$destFolderParts = $parts[0..($TargetDepth - 1)]
$destFolder = Join-Path $TargetPath ($destFolderParts -join '\')
# 确保目标目录存在
if (-not (Test-Path -LiteralPath $destFolder)) {
New-Item -ItemType Directory -Path $destFolder -Force | Out-Null
}
$destPath = Join-Path $destFolder $_.Name
# 同名自动改名
$finalDest = $destPath
$counter = 1
$baseName = [IO.Path]::GetFileNameWithoutExtension($_.Name)
$extension = $_.Extension
while (Test-Path -LiteralPath $finalDest) {
$newName = "$baseName ($counter)$extension"
$finalDest = Join-Path $destFolder $newName
$counter++
}
Move-Item -LiteralPath $fullPath -Destination $finalDest -Force
Write-Host " 已移动:$($_.Name) → $($finalDest | Split-Path -Leaf) (到第 $TargetDepth 层:$destFolder)" -ForegroundColor Gray
}
}
Write-Host "`n文件移动完成!`n正在删除所有变空的文件夹..." -ForegroundColor Yellow
# 多次循环删除空文件夹(从深到浅,确保彻底清理)
$deleted = $true
while ($deleted) {
$deleted = $false
Get-ChildItem -LiteralPath $TargetPath -Directory -Recurse | Where-Object {
(Get-ChildItem -LiteralPath $_.FullName -Recurse -File -ErrorAction SilentlyContinue).Count -eq 0
} | ForEach-Object {
try {
Remove-Item -LiteralPath $_.FullName -Force -ErrorAction Stop
Write-Host " 已删除空文件夹:$($_.FullName)" -ForegroundColor Green
$deleted = $true
} catch {}
}
}
Write-Host "`n全部处理完成!" -ForegroundColor Green
Write-Host "从第 $StartDepth 层及以下的文件已成功移动到各自所属的第 $TargetDepth 层目录,同名已自动改名,所有空文件夹已删除。" -ForegroundColor Cyan
pause
Comments