使用 Windows Control-C 剪贴板副本时如何保留制表符 `n`n?
How can I keep tab characters `n`n when using Windows Control-C clipboard copy?
我有一些不寻常的、相对 complex/large PowerShell 脚本,它通过 Write-Host 输出彩色文本。我想将整个文本输出复制到 Windows 剪贴板而不丢失制表符(使用 windows Control-C,剪贴板复制)或替代。如果我在 PowerShell.exe 控制台 Window 中运行脚本后突出显示所有文本,然后按 control-C(复制到 Windows 剪贴板)制表符将转换为空格。
如果我尝试使用下面的 Set-Clipboard cmdlet 来传输我脚本的整个输出,我的脚本中有太多组件(主要是 Write-Host 行)与进一步 PS 不兼容流水线处理;因此,下面的 Set-Clipboard 将被完全忽略(仅将输出显示到本地主机控制台)。
PS:我也试过 Start-Transcript\Stop-Transcript.. 但是,那也没有捕获标签。它将制表符转换为空格。
我希望有人有一个聪明、快速的方法来剪贴板捕获我从需要写入主机的 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)
}
}
我认为您会找到的答案是使用 Write-Host 最总是会带您走上一条您不想要的路。 Jeffrey Snover 在他的博客中对此进行了讨论。更改脚本以将 Write-Host 更改为 Write-Output 甚至可能使用颜色来决定是否应将其中一些更改为 Write-Verbose and/or 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 个空格替换回制表符,然后添加到剪贴板。 Hacky,但根据我之前关于 Write-Host 和进一步自动化所采取的路径的观点......这可能对你有用。
在那种情况下,我认为你可以使用类似的东西:
$objectsToProcess += $inputObject -replace " ", "`t"
违背专家建议..我仍然觉得我的解决方案对我的情况来说是最简单(也是最理想)的解决方案。我不会轻率地做出这个决定;特别是当人们花大量时间试图帮助我时。对不起马特!如果我的庞大脚本中还没有一百万 write-host 行,我会使用您的解决方案。
使用简单的 search\replace 重构是最简单的解决方案(在我的例子中)。我可以将我的自定义命名为 write-host,例如 'Write-Host2'。然后,只需将 Write-Host2 函数添加到我的脚本中。它将向后兼容大多数 Write-Host 参数;另外,copy-paste 和制表符兼容颜色输出到本地控制台。
我有一些不寻常的、相对 complex/large PowerShell 脚本,它通过 Write-Host 输出彩色文本。我想将整个文本输出复制到 Windows 剪贴板而不丢失制表符(使用 windows Control-C,剪贴板复制)或替代。如果我在 PowerShell.exe 控制台 Window 中运行脚本后突出显示所有文本,然后按 control-C(复制到 Windows 剪贴板)制表符将转换为空格。
如果我尝试使用下面的 Set-Clipboard cmdlet 来传输我脚本的整个输出,我的脚本中有太多组件(主要是 Write-Host 行)与进一步 PS 不兼容流水线处理;因此,下面的 Set-Clipboard 将被完全忽略(仅将输出显示到本地主机控制台)。
PS:我也试过 Start-Transcript\Stop-Transcript.. 但是,那也没有捕获标签。它将制表符转换为空格。
我希望有人有一个聪明、快速的方法来剪贴板捕获我从需要写入主机的 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)
}
}
我认为您会找到的答案是使用 Write-Host 最总是会带您走上一条您不想要的路。 Jeffrey Snover 在他的博客中对此进行了讨论。更改脚本以将 Write-Host 更改为 Write-Output 甚至可能使用颜色来决定是否应将其中一些更改为 Write-Verbose and/or 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 个空格替换回制表符,然后添加到剪贴板。 Hacky,但根据我之前关于 Write-Host 和进一步自动化所采取的路径的观点......这可能对你有用。
在那种情况下,我认为你可以使用类似的东西:
$objectsToProcess += $inputObject -replace " ", "`t"
违背专家建议..我仍然觉得我的解决方案对我的情况来说是最简单(也是最理想)的解决方案。我不会轻率地做出这个决定;特别是当人们花大量时间试图帮助我时。对不起马特!如果我的庞大脚本中还没有一百万 write-host 行,我会使用您的解决方案。
使用简单的 search\replace 重构是最简单的解决方案(在我的例子中)。我可以将我的自定义命名为 write-host,例如 'Write-Host2'。然后,只需将 Write-Host2 函数添加到我的脚本中。它将向后兼容大多数 Write-Host 参数;另外,copy-paste 和制表符兼容颜色输出到本地控制台。