将 ls 的结果通过管道传输到 Powershell 中的命令中,使用正则表达式捕获

Piping results from ls into command in Powershell, capturing with regex

我正在尝试通过将 ls 的结果传输到一个函数中来批量编辑某些视频文件的元数据,该函数在元数据中编辑视频文件的名称。示例:

文件:

元数据中所需的标题重命名:

我在 PowerShell 中使用 MKVToolNix 的 mkvpropedit 函数,它可用于按以下方式重命名单个文件的标题:

C:\"Program Files"\MKVToolNix\mkvpropedit 'My Movie 1 - 1080p DTS 5.1.mkv' -e info -s title='My Movie 1'

这非常有效,但是我希望能够对整个目录执行此操作,从元数据标题中的破折号中删除所有内容。这是我在下面尝试的代码,将 ls 的结果输送到命令中(我应该提到目录中的每个文件都是我希望编辑的电影文件)并使用正则表达式捕获文件名的所需部分。

ls | C:\"Program Files"\MKVToolNix\mkvpropedit {$_.name} -e info -s title={$_.name -replace('(.+)-.+', '')}

据我所知正则表达式是正确的,但我收到以下错误:

mkvpropedit.exe : The command parameter was already specified. At line:1 char:6

ls | C:"Program Files"\MKVToolNix\mkvpropedit {$_.name} -e info -s t ... ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

CategoryInfo : InvalidArgument: (:) [], ParameterBindingException

FullyQualifiedErrorId : ParameterSpecifiedAlready

按照评论中的建议,我也尝试了一个 foreach 循环:

ls | foreach{C:\"Program Files"\MKVToolNix\mkvpropedit {$_.name} -e info -s title={$_.name -replace('(.+)-.+', '')}} 

这产生了同样的错误,目录中的每个文件一次。 我在这里做错了什么?有没有更好的方法来达到我想要的结果?谢谢!

看起来您正在尝试使用 { ... } 块将 $_ 引用为当前 pipeline-input 变量),然而,直接调用外部可执行文件,例如mkvpropedit

相反,您必须使用 ForEach-Object 调用并使用基于 $_ 表达式 来表达您的论点:

Get-ChildItem | ForEach-Object {
  C:\"Program Files"\MKVToolNix\mkvpropedit $_.name -e info -s title=$($_.name -replace '(.+)-.+', '')
}
  • $_.name 将当前 pipeline-input 对象的($_ 的).name 属性 作为参数传递。

  • title=$($_.name -replace '(.+)-.+', '') 使用 $()subexpression operator 将表达式的结果合并到单个 title=<value> 参数中。

    • 注意:在使用 () 时,grouping operator 本身 足以将表达式的结果作为参数传递,在这种情况下复合参数,例如title=<value>,它起作用,因为PowerShell的参数绑定器认为(...)表达式是单独的参数.
      使用 $() 而不是 确实 作为复合标记工作,因为 PowerShell 然后将整个标记隐式地对待,就好像它包含在 "..." 中一样,即将它视为一个expandable string.

注意:虽然通过 C:\"Program Files"\MKVToolNix\mkvpropedit 调用确实有效,但引用风格不寻常;更典型的是,您会将 整个 路径用引号引起来:
"C:\Program Files\MKVToolNix\mkvpropedit"(或者,假设没有要扩展的变量,用单引号:
'C:\Program Files\MKVToolNix\mkvpropedit'
但是,如果路径被引用为一个整体 and/or 包含变量引用,则必须通过 &call operator 调用,出于语法原因:
& 'C:\Program Files\MKVToolNix\mkvpropedit' ...