You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell中如何正确用短横线拼接字符串数组并去除文件名前缀

解决PowerShell分割文件名后拼接出现多余短横线的问题

问题背景

你编写了以下PowerShell代码,意图去除文件名的前缀部分(例如将01 - Chapter 1 - Video 1修改为Chapter 1 - Video 1):

$count = 0
$path = "C:\Videos\"
$oldvids = Get-ChildItem -Path $path -Include *.* -Recurse
foreach ($oldvid in $oldvids) {
    $curpath = $oldvid.DirectoryName
    $name = [System.IO.Path]::GetFileNameWithoutExtension($oldvid)
    $names = $name.Split(" - ")
    $names[0] = ""
    $metadata_title = $names -join "-"
    $ext = [System.IO.Path]::GetExtension($oldvid)

    if ($name.StartsWith("new_") -eq $false)
    {
        $newvid = $curpath + "/new_" + $name + ".mp4"
        if ([System.IO.File]::Exists($newvid) -eq $false)
        {
            $count++
            
            Write-Output $metadata_title
            
        }
    }
}

但运行后发现,类似Chapter 1 - New Video的文件名会被转换为Chapter 1---New Video,出现多余的短横线,需要修正逻辑以保留单个短横线。

问题原因

  1. 使用Split(" - ")分割字符串后,将第一个元素设为空字符串,拼接时用单个"-",导致空元素与后续元素之间多出短横线。
  2. 原文件名中原本的" - "分隔符被替换成单个"-",多重叠加后就出现了连续短横线。

解决方案

方法一:用-split指定分割次数(最简洁)

直接分割第一次出现的" - ",取分割后的第二部分,完全避免拼接问题:

$count = 0
$path = "C:\Videos\"
$oldvids = Get-ChildItem -Path $path -Include *.* -Recurse
foreach ($oldvid in $oldvids) {
    $curpath = $oldvid.DirectoryName
    $name = [System.IO.Path]::GetFileNameWithoutExtension($oldvid)
    # 只分割第一次出现的" - ",获取后续部分;无分隔符时保留原文件名
    $metadata_title = if ($name -match " - ") { ($name -split " - ", 2)[1] } else { $name }
    $ext = [System.IO.Path]::GetExtension($oldvid)

    if (-not $name.StartsWith("new_"))
    {
        # 用Join-Path规范拼接路径,避免分隔符问题
        $newvid = Join-Path -Path $curpath -ChildPath "new_$name.mp4"
        if (-not [System.IO.File]::Exists($newvid))
        {
            $count++
            Write-Output $metadata_title
        }
    }
}

方法二:修正Split与拼接逻辑

如果坚持使用Split方法,需移除空元素后,用原分隔符" - "拼接剩余部分:

$count = 0
$path = "C:\Videos\"
$oldvids = Get-ChildItem -Path $path -Include *.* -Recurse
foreach ($oldvid in $oldvids) {
    $curpath = $oldvid.DirectoryName
    $name = [System.IO.Path]::GetFileNameWithoutExtension($oldvid)
    # 分割时移除空元素,避免首尾空格导致的无效项
    $names = $name.Split(" - ", [System.StringSplitOptions]::RemoveEmptyEntries)
    # 分割后元素数量大于1时,取第二个及以后的元素用原分隔符拼接
    $metadata_title = if ($names.Count -gt 1) { $names[1..($names.Count-1)] -join " - " } else { $name }
    $ext = [System.IO.Path]::GetExtension($oldvid)

    if (-not $name.StartsWith("new_"))
    {
        $newvid = Join-Path -Path $curpath -ChildPath "new_$name.mp4"
        if (-not [System.IO.File]::Exists($newvid))
        {
            $count++
            Write-Output $metadata_title
        }
    }
}

额外优化建议

  • 用Join-Path代替直接拼接路径字符串,适配不同系统的路径分隔符,代码更健壮。
  • 用-not代替-eq $false,符合PowerShell的习惯写法。
  • 增加无分隔符文件名的处理逻辑,避免数组索引越界错误。

内容的提问来源于stack exchange,提问作者Joan Venge

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 07:15:34