【问题标题】:How can I keep tab characters `n`n when using Windows Control-C clipboard copy?使用 Windows Control-C 剪贴板副本时如何保留制表符`n`n?
【发布时间】:2016-03-29 01:54:20
【问题描述】:

我有一些不寻常的、相对复杂/大型的 PowerShell 脚本,它通过 Write-Host 输出彩色文本。我想将整个文本输出复制到 Windows 剪贴板而不丢失制表符(使用 Windows Control-C、剪贴板副本)或替代。如果在脚本在 PowerShell.exe 控制台窗口中运行后突出显示所有文本,然后按 control-C(复制到 Windows 剪贴板),制表符将转换为空格。

如果我尝试使用下面的 Set-Clipboard cmdlet 来管道我的脚本的整个输出,我的脚本中有太多的组件(主要是 Write-Host 行)与进一步的 PS 管道处理不兼容;因此,下面的 Set-Clipboard 完全被忽略(仅显示输出到本地主机控制台)。

PS:我也尝试过 Start-Transcript\Stop-Transcript.. 但是,这也没有捕获标签。它将制表符转换为空格。

我希望有人有一个聪明、快速的方法来剪贴板捕获我从需要 write-host 的 cmdlet 获得的文本,该写主机还捕获 `t 制表符。

invoke-myscript -Devicename "WindowsPC" | Set-Clipboard
function Set-Clipboard {

param(
    ## The input to send to the clipboard
    [Parameter(ValueFromPipeline = $true)]
    [object[]] $InputObject
)

begin
{
    Set-StrictMode -Version Latest
    $objectsToProcess = @()
}

process
{
    ## Collect everything sent to the script either through
    ## pipeline input, or direct input.
    $objectsToProcess += $inputObject
}

end
{
    ## Launch a new instance of PowerShell in STA mode.
    ## This lets us interact with the Windows clipboard.
    $objectsToProcess | PowerShell -NoProfile -STA -Command {
        Add-Type -Assembly PresentationCore

        ## Convert the input objects to a string representation
        $clipText = ($input | Out-String -Stream) -join "`r`n"

        ## And finally set the clipboard text
        [Windows.Clipboard]::SetText($clipText)
    }
}

【问题讨论】:

  • 为什么不直接将输出作为 HTML 输出写入文件?或其他一些富文本。听起来你真的只想要颜色而不是任何东西,并试图解决错误的问题。也就是说,Write-Host 不使用输出流,所以你不会在管道中得到任何东西。启用 CSS 的 HTML 输出听起来更通用
  • 嘿,马特。非常感谢您的建议。任何想法如何转换具有大量行的脚本,例如 write-host -NoNewline -ForegroundColor "Gray" "Circuit:tt`t"; write-host -ForegroundColor "DarkYellow" "$Circuit"
  • 您需要使用@name 来回复他人。我不知道你回复了。就像我说的,我认为你应该尝试不同的方法。您能否展示您希望输出的样例以及如何生成$circut 这应该很容易替换。这是一个高效的问题。
  • 您可以使用 powershell_ise 来运行您的脚本吗?控制台确实会丢失选项卡,但 ISE 不会。

标签: windows powershell tabs clipboard


【解决方案1】:

违背专家的建议。我仍然觉得我的解决方案是最简单(也是最理想)的解决方案。我不会轻易做出这个决定。尤其是当人们花费大量时间试图帮助我时。很抱歉,马特!如果我的庞大脚本中没有一百万行 write-host 行,我会使用您的解决方案。

用简单的搜索\替换重构是最简单的解决方案(在我的例子中)。我可以将我的自定义写入主机命名为“Write-Host2”。然后,只需将 Write-Host2 函数添加到我的脚本中。它将与大多数 Write-Host 参数向后兼容;另外,复制粘贴和制表符与颜色输出到本地控制台兼容。

【讨论】:

    【解决方案2】:

    我认为您会找到的答案是,使用 Write-Host 总是会带您走上您不想要的道路。 Jeffrey Snover 在他的博客中讨论了这个问题。更改脚本以将 Write-Host 更改为 Write-Output 可能值得一试,甚至可能使用颜色来决定是否应将其中一些更改为 Write-Verbose 和/或 Write-Warning。

    如果您这样做,那么您可以使用其他选项,例如使用 -OutVariable 精确捕获输出以进行进一步处理(自动化)。

    下面的示例展示了这样的变化如何使您受益。

    function print-with-tab {
      [cmdletbinding()]
      Param()
    
      Write-Host "HostFoo`t`t`tHostBar"
      Write-Output "OutFoo`t`t`tOutBar"
      Write-Warning "You have been warned."
    }
    
    print-with-tab -OutVariable outvar -WarningVariable warnvar
    
    Write-Output "Out -->"
    $outvar
    # proof there's tabs in here
    $outvar -replace "`t", "-"
    Write-Output "Warn -->"
    $warnvar
    

    输出

    HostFoo         HostBar
    OutFoo          OutBar
    WARNING: You have been warned.
    Out -->
    OutFoo          OutBar
    OutFoo---OutBar
    Warn -->
    You have been warned.
    

    最后的想法

    最后的想法是,如果您知道您没有任何包含 4 个空格的字符串(如果这是您的制表符变成的),那么获取您的输出,将所有出现的 4 个空格替换为制表符,然后添加到剪贴板。哈克,但根据我之前关于您使用 Write-Host 和进一步自动化的路径的观点......这可能对您有用。

    在这种情况下,我认为您可以使用以下内容:

    $objectsToProcess += $inputObject -replace "    ", "`t"
    

    【讨论】:

    • @Keri Gill.. 非常感谢,这对制作新脚本很有帮助。就我而言,在脚本中创建自己的 write-host 函数可能更容易。这样我就不需要更改具有写入主机的每一行。我只需要弄清楚如何处理 NoNewLine 开关。
    • 是否有一个 write-host 函数的副本,我可以从某个地方复制,这样我就不必从头开始制作它了?然后我可以添加功能,使带有标签的 Windows 剪贴板兼容。
    • 搜索“powershell 覆盖写入主机”。 stackoverflow.com/questions/14470953/…byteonmyside.wordpress.com/2012/04/25/…。等
    • @MKANET Write-Host 不应超载,因为它会产生误导。它并不意味着只创建控制台文本的输出。我认为您应该使用带有变量的日志记录函数,以便您可以在执行时决定数据的去向。也可以转换为写调试?无论哪种方式,您似乎都在滥用 write-host,并且为了您自己,无论如何都应该替换它。查找替换不是一项艰巨的任务。您的标签问题似乎也不是您真正的问题。
    • 感谢您的有效积分。使用简单的搜索\替换进行重构是最简单的解决方案(在我的情况下)。我可以将我的自定义写入主机命名为“Write-Host2”。然后,只需将 Write-Host2 函数添加到我的脚本中。它将与大多数 Write-Host 参数向后兼容;另外,复制粘贴和制表符与颜色输出到本地控制台兼容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多