我想在cmd.exe .bat脚本中指定多行PowerShell命令。我显然还没有正确的续行和/或引用。我也尝试使用反引号作为具有类似失败的行继续符。如何正确输入?
PS C:\src\t> cat .\pd.bat
powershell -NoProfile -Command "Get-ChildItem -Path '../' -Filter '*.doc' | ^
Select-Object -First 1 | ^
ForEach-Object { notepad `"$_.FullName`" }"
PS C:\src\t> .\pd.bat
C:\src\t>powershell -NoProfile -Command "Get-ChildItem -Path '../' -Filter '*.doc' | ^
^ : The term '^' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if
a path was included, verify that the path is correct and try again.
At line:1 char:45
+ Get-ChildItem -Path '../' -Filter '*.doc' | ^
+ ~
+ CategoryInfo : ObjectNotFound: (^:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
答案 0 :(得分:7)
如果不使用中间临时文件,您可以使用选择性^
- 转义:
powershell -NoProfile -Command Get-ChildItem -Path '../' -Filter '*.doc' ^| ^
Select-Object -First 1 ^| ^
ForEach-Object { notepad "\"$($_.FullName)\"" }
请注意,notepad "$_.FullName"
在PowerShell中不起作用,因为您需要在$(...)
内附加"..."
来引用属性。我已经纠正了上面的问题,但请注意,在这种情况下你根本不需要双引号。
^
:
|
以阻止cmd.exe
提前解释。
^
的元字符传递给PowerShell,则必须cmd.exe
- 转义所有的& | < > %
元字符:"
\
个实例,您希望PowerShell看到字面上(对于它们,当解释为PowerShell源代码时,它们具有 syntatic 含义)是一种特殊情况:你必须"..."
- 逃避它们(!)和 cmd.exe
- 用PowerShell包含你想要被识别为单个参数的字符串,这样至于准确保存嵌入空白。^
该命令在下一行继续。
^
必须是该行的最后一个字符。python -c
会删除换行符,因此生成的命令是单 -line命令。在您的命令中包含实际换行符 - 必需,用于将命令传递给使用^<newline><newline>
的Python等语言,为{{3} }指出 - 使用powershell.exe -noprofile -command "\"line 1^
line 2\""
,因为eryksun建议:
line 1
line 2
以上产量(基于PowerShell简单地回显(输出)作为命令提交的引用字符串文字):
"\"
注意:\""
(和匹配的"
)不仅要求最终传递在此处正确保留嵌入空格的字符串,还要提供平衡 cmd.exe
的一行\
到cmd.exe
(无论^
- 逃避,'...'
无法识别) - 没有它,换行符powershell.exe -noprofile -command ^"'line 1^
line 2'^"
1}}在该行的末尾将无法识别。
PetSerAl还指出,如果您传递的是PowerShell应该将字符串 literal 传递给您,您还可以传递PowerShell最终看到的单引号字符串(^
):
"
此处,cmd.exe
- ^
实例的转义是为了.slice(-n)
的利益,因此它不会将换行符n
误认为是.slice()
双引号字符串。
答案 1 :(得分:2)
我是第二个Bill_Stewart的评论,只是在原生PowerShell控制台中做到这一点;不需要cmd。
如果需要在cmd中执行此操作,请在使用^
之前为每行使用引号。并从ForEach-Object
块中删除反引号。
powershell -NoProfile -Command "Get-ChildItem -Path '../' -Filter '*.doc' |" ^
"Select-Object -First 1 ^| ^
"ForEach-Object { notepad "$_.FullName" }
答案 2 :(得分:1)
我通常会采取相反的做法,并尽可能将命令折叠为1行。您可以通过终止命令来执行此操作;就像javascript或c#一样。在您的情况下,我甚至不需要使用终结器。您可以将其转换为一行:
powershell -NoProfile -Command "Get-ChildItem -Path '../' -Filter '*.doc' | Select-Object -First 1 | ForEach-Object { notepad `"$_.FullName`" }"
另一种选择是将PowerShell保存到外部文件并调用它:
powershell.exe -File MyPSScript.ps1
答案 3 :(得分:1)
pd.bat内容必须如下:
powershell -NoProfile -Command Get-ChildItem -Path '../' -Filter '*.doc' ^| ^
Select-Object -First 1 ^| ^
ForEach-Object { notepad $_.FullName }