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