使用cmd.exe中的多行PowerShell命令

时间:2017-07-20 20:39:34

标签: powershell cmd

我想在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

4 个答案:

答案 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 }