使用PowerShell ISE批量修改文件名时间:减去指定偏移秒数
批量重命名TS文件:替换录制时间为节目实际开播时间
需求说明
有存储.ts文件的文件夹,文件名格式统一,例如:(15.02.22 11-55-45 - timeshift 145544 s) News (TVP Wilno HD).ts
其中括号内的时间为录制请求时间,节目实际开播时间比该时间早145544秒(即文件名中timeshift后的数字)。需要批量将文件名中的时间替换为节目开播时间,示例文件最终需命名为:(13.02.22 19-30-00) Wiadomosci (TVP Wilno HD).ts
原脚本及错误信息
原PowerShell脚本
$folderPath = "D:\test" $files = Get-ChildItem -Path $folderPath -Filter "*.ts" foreach ($file in $files) { $fileName = $file.Name $startTimeSeconds = $fileName.Substring($fileName.IndexOf("timeshift") + 10, 6) $startTime = [datetime]::ParseExact($fileName.Substring(1, 18), "dd.MM.yy HH-mm-ss", $null) $startTime = $startTime.AddSeconds(-$startTimeSeconds) $newFileName = "(" + $startTime.ToString("dd.MM.yy HH-mm-ss") + ") " + $fileName.Substring($fileName.IndexOf(")") + 2) Rename-Item $file.FullName -NewName $newFilename }
错误信息
调用“ParseExact”时发生异常,参数计数为“3”:“字符串未被识别为有效的DateTime。” At line:7 char:5 + $startTime = [datetime]::ParseExact($fileName.Substring(1, 18), " ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : FormatException 方法调用失败,因为[System.Object[]]不包含名为“AddSeconds”的方法。 At line:8 char:5 + $startTime = $startTime.AddSeconds(-$startTimeSeconds) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : MethodNotFound 找不到“ToString”的重载,参数计数:“1”。 At line:9 char:5 + $newFileName = "(" + $startTime.ToString("dd.MM.yy HH-mm-ss") + " ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodException + FullyQualifiedErrorId : MethodCountCouldNotFindBest
错误原因分析
- 时间字符串截取错误:
Substring(1,18)会截取到包含多余字符的字符串(如15.02.22 11-55-45 -),不符合dd.MM.yy HH-mm-ss的格式,导致ParseExact解析失败。 - 秒数类型错误:
$startTimeSeconds是字符串类型,而AddSeconds需要整数参数,导致方法调用失败。 - 变量大小写不一致:脚本中定义
$newFileName,但重命名时使用$newFilename,可能引发意外问题。 - 固定位置截取不可靠:依赖硬编码的位置截取文件名内容,一旦文件名格式有细微变化就会出错。
修正后的PowerShell脚本
使用正则表达式匹配文件名中的关键信息,更稳定可靠:
$folderPath = "D:\test" Get-ChildItem -Path $folderPath -Filter "*.ts" | ForEach-Object { # 正则匹配录制时间、timeshift秒数、节目名称 if ($_.Name -match '\((\d{2}\.\d{2}\.\d{2} \d{2}-\d{2}-\d{2}) - timeshift (\d+) s\) (.+)\.ts') { $recordTimeStr = $matches[1] $shiftSeconds = [int]$matches[2] $programName = $matches[3] # 解析录制时间(使用InvariantCulture避免区域设置影响) $recordTime = [datetime]::ParseExact( $recordTimeStr, "dd.MM.yy HH-mm-ss", [System.Globalization.CultureInfo]::InvariantCulture ) # 计算节目实际开播时间 $airTime = $recordTime.AddSeconds(-$shiftSeconds) # 生成新文件名 $newName = "($($airTime.ToString('dd.MM.yy HH-mm-ss'))) $programName.ts" # 预览重命名结果(去掉-WhatIf即可执行实际重命名) Rename-Item -Path $_.FullName -NewName $newName -WhatIf } }
脚本说明
- 正则匹配:通过正则精准提取录制时间、偏移秒数和节目名称,不受固定位置限制。
- 类型转换:将偏移秒数转为整数,确保
AddSeconds方法正常调用。 - 区域无关解析:使用
InvariantCulture解析时间,避免系统区域设置导致的格式错误。 - 预览模式:默认添加
-WhatIf参数,可先查看重命名结果,确认无误后再移除该参数执行实际操作。
内容的提问来源于stack exchange,提问作者Archiwa telewizyjne ZAPASOWY
相关产品推荐
相关产品推荐

