删除包含关键字,比如包含关键字"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

使用方法

  1. 新建文本文件,复制以上全部内容粘贴。

  2. 只修改一行:

    $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

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

登录

注册

重设密码

请输入您的用户名或电子邮箱地址。您会收到一封包含创建新密码链接的电子邮件。