执行Windows Powershell命令将文本复制到剪贴板(包括`r`n')

时间:2018-07-18 09:31:22

标签: powershell

我正在尝试执行powershell命令将文本复制到Windows剪贴板,包括回车符和所有特殊字符。我可以使用以下命令执行ok:

powershell.exe -command Set-Clipboard 'TEXT'

这不是直接在Powershell控制台中,因此语法有所不同。

我在文本周围使用双引号,在原始文本中用`r`n代替回车,并用`转义所有其他特殊字符。 直到我找到一个',据我了解Powershell都使用它来表示文字文本字符串。

因此,我更改了方法并将未转义的文本用单引号引起来(用1'替换为2”)。当然,单引号内的`r`n是按字面意义解释的,因此不起作用。我试过将它们用单引号括起来,例如:

'some text here' "`r`n" 'more text here'

这在控制台中有效,但在命令中无效。尝试在任一侧添加+,但仍然无法正常工作。

用户“ TessellatingHeckler”建议使用-EncodedCommand,但是不幸的是,我无法生成任何版本的base 64编码的字符串(包括在命令中),这些版本与通过PS控制台编码的相同字符串匹配。所以那是行不通的。

我一直在尝试用晦涩的字符串简单地替换原始文本中的回车,将文本用单引号引起来(文字上),然后在PS中将其替换回`r`n。我已经获得了替代品,可以直接在控制台中工作,但无法弄清楚如何将其作为命令实际发送。

powershell.exe -command Set-Clipboard $Str = 'this is a test--INSERT_CRLF_HERE--1234'; $Car = '--INSERT_CRLF_HERE--'; $clr = "`r`n"; $Str = $Str -replace $Car, $clr

可以将上述命令修改为起作用吗?是否可以在不写入临时文件的情况下实现预期的结果?最好使用单引号引起来的文本块,因为它比尝试转义原始文本中的所有内容(甚至空格)更健壮和轻巧。

2 个答案:

答案 0 :(得分:1)

Rob Simmers在另一个正在使用的论坛上得知了一个相当整洁的解决方案。

原始文本:

Test text
!@#$%^&*()_+-=[]\{}|;':",./<>?

以5个字符替换的字符串({ = {{} = }}' = '',crlf = {0}" = {1}):

Test text{0}!@#$%^&*()_+-=[]\{{}}|;'':{1},./<>?

Powershell.exe命令:

powershell.exe -command "$str = 'Test text{0}!@#$%^&*()_+-=[]\{{}}|;'':{1},./<>?' -f [System.Environment]::NewLine, [Char] 0x22 ; Set-Clipboard $str"

输出(放置在剪贴板上的文字)-根据需要与输入相同:

Test text
!@#$%^&*()_+-=[]\{}|;':",./<>?

答案 1 :(得分:0)

顺便说一句:任何调用方案中都可以使用的完全健壮的解决方案确实需要使用-EncodedCommand Base64编码的字符串 UTF16-LE 字节表示形式的em> -但您已经声明创建这样的字符串不是您的选择。
如果要从PowerShell中调用,则可以更简单地使用脚本块(请参见底部)。

更新OP's own answer现在包含一个基于仔细的字符串替换的健壮的(即使不平凡的)解决方案。
对于更简单的方案以及有关报价要求和陷阱的背景信息,下面的答案可能仍然很有趣。


使用问题中的场景,此更简单的解决方案应该可以(通过cmd.exe进行验证-我们仍然不知道您从何处调用PowerShell,但是如果 no shell ))

powershell.exe -command "Set-Clipboard \"this is`r`na test\""

其他特殊字符:

  • '可以按原样嵌入-无需转义
  • "需要转义为`\"
  • $`$相同,但前提是您希望将其视为文字(在常规的双引号PowerShell字符串中应用相同的转义)

如果您的用例需要传递任意一个预先存在的字符串,则必须使用字符串替换来执行上述转义操作-包括用文字`r`n替换嵌入的换行符。

如果不涉及 外壳程序(例如Python中的subprocess.check_output()),则上述规则应足以满足要求,并提供了一个可靠的解决方案(假设您仅使用可打印的字符,并且没有字符编码问题。

cmd.exe开始,一个不使用-EncodedCommand的完全健壮的解决方案需要额外的,琐碎的工作,因为它缺乏对嵌入式双引号的正确解析:

以下cmd.exe元字符通常 需要转义^,但有时 不能转义:
& | < >

在以下示例中,&需要转义^

powershell.exe -command "Set-Clipboard \"this is`r`na ^& test\""

但是,如果您的字符串也已经嵌入(并转义了)"个字符,则这些字符是否需要^进行转义取决于它们相对于嵌入的"的位置 ;请注意,在以下示例中,&不需要 逃脱^,而实际上一定不能,因为^成为字符串的一部分:

powershell.exe -command "Set-Clipboard \"this is`r`na 3`\" & test\""

从算法上预见到这些变化是一项艰巨的任务。

此外,如果您的字符串包含%...%标记,它们看起来像cmd.exe风格的环境变量,例如%FOO%-但您想将它们视为 literal % 不能转义。

有一种解决方法可以起作用,但这又取决于嵌入的"字符的存在和放置。

在下面的示例中,"^ disrupter" trick可用于防止%OS%扩展:

powershell.exe -command "Set-Clipboard \"do not expand: %^OS%\""

但是,如果在其之前嵌入了",则解决方法将失效(保留^),并且在这种情况下我没有直接的解决方法:

powershell.exe -command "Set-Clipboard \"do not expand: 3`\" %^OS%\""

您必须将字符串分成多段,以将%OS%令牌分开,并通过PowerShell表达式将各段连接起来:

powershell.exe -command "Set-Clipboard (\"do not expand: 3`\" %\" + \"OS%\")"

从算法上讲,您可以使用占位符。然后将其替换为PowerShell命令的一部分,这是您在自己的答案中使用的一种技术。


顺便说一句:

如果您想从
PowerShell 中执行 ,则需要

额外转义:

powershell.exe -command "Set-Clipboard \`"this is`r`na test\`""

但是,从PowerShell构造一个Base64编码的字符串传递给 -EncodedCommand,但是还有一个更简单的方法:使用脚本块传递命令;在这种情况下,没有额外的报价要求
请注意,此 only 仅可在PowerShell中使用。

powershell.exe -command { Set-Clipboard "this is`r`na test" }