Powershell 将目录内容发送到程序

Powershell send directory contents to a program

我的目标是使用可将目录中的 .wav 文件转换为正确的音频格式的可执行文件来处理目录中的 .wav 文件。创建这些文件后,我需要将目录中的所有内容移至另一个目录目标。应该发生的是一旦文件执行程序 (CommandLineConverter.exe) 就会以正确的音频格式创建一个新文件。

我试过 Get-ChildItem 指向可执行文件。早些时候我 运行 遇到脚本接受 (x86) 的问题。但是,现在似乎已经解决了,我在调试时没有任何错误。 Move-Item 现在被注释掉了,因为我正在尝试转换文件。目前脚本不转换文件。我看不到任何输出。

我考虑过打开目录($path)中的每个项目作为替代方案,因为我设置了在 CommandLineConverter.exe 中打开 wave 文件的默认值;然而,那个剧本也不顺利。

无论如何,这里是我到目前为止用于将目录内容发送到可执行文件的脚本,但似乎没有按预期工作。任何帮助我指出正确方向的帮助将不胜感激。

$path= "C:\Execuscribe\ExecuDropBox\Dropbox (ExecuScribe)\Conduent\Verizon"
$destination= "C:\Execuscribe\ExecuDropBox\Dropbox (ExecuScribe)\Converted"
Get-ChildItem $path | ForEach-Object 'C:\Program Files (x86)\Verint\Playback\CommandLineConvertor.exe'
#   {
        
 #       Move-Item -Path $file.fullname -Destination $Destination
#    }

柯克,

我想你想要这样的东西:

$path= "C:\Execuscribe\ExecuDropBox\Dropbox (ExecuScribe)\Conduent\Verizon"
$destination= "C:\Execuscribe\ExecuDropBox\Dropbox (ExecuScribe)\Converted"
Get-ChildItem $path  -Filter "*.wav" | 
ForEach-Object {
   &  'C:\Program Files (x86)\Verint\Playback\CommandLineConvertor.exe' $($_.FullName)

  $MIArgs = @{Path = $($_.fullname) 
              Destination = "$Destination"}
   Move-Item @MIArgs
}

将 -Filter 参数添加到 Get-ChildItem 以仅检索 .wav 文件。 调用指定每个文件的程序,因为它通过管道。我不知道转换器的参数是如何指定的,但包含的代码只包含完全限定的文件名,您可以添加所需的任何标识符。 将转换后的文件复制到新位置,您必须将 NewExt 替换为转换后文件的输出扩展名。

这是未经测试的代码!

包含关键指针:

  • 您必须将对可执行文件的调用放在 script block ({ ... }) passed to ForEach-Object ...

  • ... 而且,因为可执行文件的路径是(必然)引用,您必须通过 & 调用,call operator.

  • 此外,您必须通过 automatic $_ variable 将每个输入文件的完整路径作为 显式参数 传递给您的可执行文件,这反映了管道手头的输入对象。

    • WindowsPowerShell中,您必须使用$_.FullName来确保输入文件的完整路径是通过;幸运的是,在 PowerShell (Core) 7+ 中不再需要这样做,其中 $_ 就足够了。

但是,关于重命名部分,我建议通过 Get-Item, which you can then pipe to a single Move-Item 调用在新的最终管道段中检索转换的输出文件:

Get-ChildItem -LiteralPath $path | ForEach-Object { 
  & 'C:\Program Files (x86)\Verint\Playback\CommandLineConvertor.exe' $_.FullName  
  Get-Item -LiteralPath (Join-Path $_.DirectoryName ($_.BaseName + '_Conv.wav'))
} | Move-Item -Destination $destination

注:

  • -LiteralPath 用于稳健性,以确保所有路径都按字面意思 处理,而不是 wildcard expressions,就像会发生的那样如果您改为使用 -Path(可能在位置上 隐含 ,例如在您的 Get-ChildItem $path 调用中)。

  • $_.DirectoryName 是输入文件的 目录 路径。 $_.BaseName + '_Conv.wav' 采用输入文件名的基本名称(不带扩展名的文件名)并附加 _Conv.wav 以标识转换输出文件名。然后将这两条信息与 Join-Path 连接起来形成输出文件的完整路径。

  • 请注意,将转换输出文件路径传递给 Get-Item -LiteralPath 并非绝对必要,但它再次确保绑定到 (Move-Item's) -LiteralPath范围。虽然 Move-Item 也接受路径 strings 作为管道输入,但它们绑定到 -Path 参数,因此再次被解释为通配符表达式,这尤其会导致包含 [ 个字符(例如 file[1].wav)的文字路径失败。

问题主要通过 RetiredGeek 的代码和建议解决。此代码的唯一问题是转换后的文件保留在源目录或 $path 中。我添加了另一个备份目录并将未转换的文件发送到备份,使用 mklement0 的代码能够将转换后的文件移至 Converted 目录。

$path= "C:\Execuscribe\ExecuDropBox\Dropbox (ExecuScribe)\Conduent\Verizon"
$destination= "C:\Execuscribe\ExecuDropBox\Dropbox (ExecuScribe)\Converted"
$backup= "C:\Execuscribe\ExecuDropBox\Dropbox (ExecuScribe)\Backup"
Get-ChildItem $path  -Filter "*.wav" | 
ForEach-Object {
   &  'C:\Program Files (x86)\Verint\Playback\CommandLineConvertor.exe' $($_.FullName)

$MIArgs = @{Path = $($_.fullname) 
            Destination = "$backup"}
   Move-Item @MIArgs

   Get-Item (Join-Path $_.DirectoryName ($_.BaseName + '_Conv.wav'))
  } | Move-Item -Destination $destination