将命令行转换为powershell

将命令行转换为powershell,powershell,cmd,Powershell,Cmd,EDIT2:下面的最终代码 我需要关于转换一些代码的帮助,因为我对mkvmerge、powershell和命令提示符非常陌生 CMD代码来自 对于(*.mkv)中的%%f,执行%mkvmerge%@options.json-o“mkvmerge_out/%f”“%f” 到目前为止我所做的 $SourceFolder = "C:\tmp" #In my actual code, this is done using folder browser $SourceFiles = Get-Child

EDIT2:下面的最终代码

我需要关于转换一些代码的帮助,因为我对mkvmerge、powershell和命令提示符非常陌生

CMD代码来自

对于(*.mkv)中的%%f,执行%mkvmerge%@options.json-o“mkvmerge_out/%f”“%f”

到目前为止我所做的

$SourceFolder = "C:\tmp" #In my actual code, this is done using folder browser
$SourceFiles = Get-ChildItem -LiteralPath $SourceFolder -File -Include *.mkv
$SourceFiles | foreach
{
    start-process "F:\Desktop\@progs\mkvtoolnix\mkvmerge.exe"
}
我将非常感谢任何帮助,因为我在学习双方的同时,在理解和转换方面遇到了困难。多谢各位

**编辑2:*这是我最后的工作代码

Function Get-Folder($initialDirectory) {

    #Prompt to choose source folder
    [void] [System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
    $FolderBrowserDialog = New-Object System.Windows.Forms.FolderBrowserDialog
    $FolderBrowserDialog.Description = 'Choose the video folder'
    $FolderBrowserDialog.RootFolder = 'MyComputer'
    if ($initialDirectory) { $FolderBrowserDialog.SelectedPath = $initialDirectory }
    [void] $FolderBrowserDialog.ShowDialog()
    return $FolderBrowserDialog.SelectedPath


}

Function ExitMessage 
{
#endregion Function output
Write-Host "`nOperation complete";
Write-Host -NoNewLine 'Press any key to continue...';
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
Exit;
}

($SourceFolder = Get-Folder  | select )

#Check for output folder and create if unavailable
$TestFile = "$SourceFolder" + "\mkvmerge_out"
if ((Test-Path -LiteralPath $TestFile) -like "False")
{
    new-item -Path $SourceFolder -name "mkvmerge_out" -type directory
    Write-Host 'Folder created';
}

#Checking for the presence of a Json file
$TestFile = (Get-ChildItem -LiteralPath $SourceFolder -File -Filter *.json)
if ($TestFile.count -eq 0)
{
    Write-Host 'json file not found';
    ExitMessage;
}
$TestFile = "$SourceFolder" + "\$TestFile"


#Getting the total number of files and start timer.
[Int] $TotalFiles = 0;
[Int] $FilesDone = 0;
$TotalFiles = (Get-ChildItem -LiteralPath $SourceFolder -File -Filter *.mkv).count
$PercentFiles = 0;
$Time = [System.Diagnostics.Stopwatch]::StartNew()

#Start mkvmerge process with progress bar
$mkvmergeExe = 'F:\Desktop\@progs\mkvtoolnix\mkvmerge.exe'
$JsonFile = "$TestFile" # alternatively, use Join-Path
Get-ChildItem -LiteralPath $SourceFolder -File -Filter *.mkv | ForEach-Object {
    $PercentFiles = [math]::truncate(($FilesDone/$TotalFiles)*100)
    Write-Progress -Activity mkvmerge -Status ("{0}% Completed; {1}/{2} done; Time Elapsed: {3:d2}:{4:d2}:{5:d2}" -f $PercentFiles, $FilesDone, $TotalFiles, $Time.Elapsed.Hours, $Time.Elapsed.minutes, $Time.Elapsed.seconds) -PercentComplete $PercentFiles;
    Write-Host "Processing $_"
    $f = $_.FullName
    $of = "$SourceFolder\mkvmerge_out\$($_.Name)"
    & $mkvmergeExe -q `@$JsonFile -o $of $f
    $FilesDone++
}

Remove-Item -LiteralPath $JsonFile #Remove this line if you want to keep the Json file
$PercentFiles = [math]::truncate(($FilesDone/$TotalFiles)*100)
Write-Progress -Activity mkvmerge -Status ("{0}% Completed; {1}/{2} done; Time Elapsed: {3:d2}:{4:d2}:{5:d2}" -f $PercentFiles, $FilesDone, $TotalFiles, $Time.Elapsed.Hours, $Time.Elapsed.minutes, $Time.Elapsed.seconds) -PercentComplete $PercentFiles;
ExitMessage;
请注意,
cmd
代码假定它在当前目录中运行,而PowerShell代码通过
$SourceFolder
显式传递目录;因此,必须在
$SourceFolder
中查找
options.json
文件,并且传递到
-o
的输出文件路径也必须以
$SourceFolder
作为前缀,这是通过(
“…”
实现的)。

需要考虑的要点:

  • (*.mkv)中%%f的
    在PowerShell中没有直接对应项;您正确地使用了,以获取匹配文件的列表,这些文件作为实例返回

    • 但是,
      -Include
      在缺少
      -Recurse
      的情况下无法按预期工作(除非附加
      \*
      -see;
      -Filter
      可以,而且是更快的方法,但它有其局限性和遗留问题(请参见)
  • 虽然PowerShell也允许您执行其名称或路径存储在变量中(或指定为带引号的字符串文字)的命令,但出于语法原因,您需要调用它

  • 在传递给cmdlet的(
    {…}
    )中,
    $\
    表示当前的管道输入对象

    • $\u.FullName
      确保在字符串上下文中使用时,
      System.IO.FileInfo
      输入实例由其完整路径表示

    • 在PowerShell[Core]6+中不再需要这个额外的步骤,幸好在那里,
      System.IO.FileInfo
      实例总是作为其完整路径进行字符串化

  • @
    字符前面有
    `
    (反勾),PowerShell的转义字符,因为
    @
    -不同于
    cmd
    -是一个元字符,即具有特殊语法意义的字符。
    `
    确保
    @
    被逐字处理,因此传递到
    mkvmerge

    • 或者,您可以引用参数,而不是仅转义
      @
      “@$optionsFile”

    • 有关背景信息,请参阅

  • 您通常不需要在PowerShell的
    “…”
    中包含参数,即使它们包含空格或其他元字符

$mkvmergeExe = 'F:\Desktop\@progs\mkvtoolnix\mkvmerge.exe'
$optionsFile = "$SourceFolder\options.json" # alternatively, use Join-Path
Get-ChildItem -LiteralPath $SourceFolder -File -Filter *.mkv | ForEach-Object {
  $f = $_.FullName
  $of = "$SourceFolder\mkvmerge_out\$($_.Name)"
  & $mkvmergeExe `@$optionsFile -o $of $f
}