Powershell和管道的cmd问题

时间:2018-09-26 22:59:00

标签: powershell cmd

我有此命令可以在Powershell上正常工作

Compare-Object (Get-Content "tex1.txt") (Get-Content "tex2.txt") | Where-Object{$_.SideIndicator -eq "<="} | select inputobject |  ft -hidetableheaders

我正在尝试通过以下方式在cmd中运行:

powershell -Command " & {Compare-Object (Get-Content "tex1.txt") (Get-Content "tex2.txt") | Where-Object{$_.SideIndicator -eq "<="} | select inputobject |  ft -hidetableheaders}"

但它表示类似:名称,目录或卷语法不正确(是西班牙语,所以我不知道确切的翻译)

我认为问题出在管道上,因为在管道之前运行所有内容:Compare-Object (Get-Content "tex1.txt") (Get-Content "tex2.txt")可以正常工作

PD:我也尝试在管道之前写^,但没有成功。

1 个答案:

答案 0 :(得分:4)

tl; dr

在整个"字符串中使用嵌入式"..."会带来一些挑战。如果可行,构造没有嵌入式"的PowerShell命令是最简单的解决方案:

powershell -Command "Compare-Object (Get-Content tex1.txt) (Get-Content tex2.txt) | Where-Object {$_.SideIndicator -eq '<='} | select inputobject |  ft -hidetableheaders"

请继续阅读,如果您确实需要使用嵌入式"


eryksun指出您的问题是您的在整个"字符串内缺少转义的"..."字符的转义。 }查看多个字符串,包括它认为未加引号的的部分,这会导致特殊字符(例如cmd.exe|的问题-它们永远不会到达< em> PowerShell 。

<中的

嵌套双引号字符串很棘手:

  • 要使cmd.exe高兴,您需要 double 嵌入的cmd.exe字符。 ("
  • 另外,要使""开心,您需要powershell.exe逃逸\字符。
    • 注意:Windows上的跨平台版本PowerShell Core 现在也可以单独接受",这是最可靠的选择。

通常,与{Unix}不同,在没有通用解决方案的情况下,从""调用时处理引号和转义参数是令人沮丧的经历。可悲的是,即使在Unix世界中, PowerShell 也有其自身的挑战。 [1]

简而言之:转义嵌入的cmd.exe字符。从" 调用 Windows PowerShell 时,如下所示:

  • 在使用cmd.exe 时使用\"" (原文如此),如果保持空白不变 必需
    这样可以避免其他转义,但是powershell.exe -Command运行之间的空格不会保留,因此,例如,此方法不适合传递JSON字符串。

    • 注意事项\""...\"" 在调用其他程序时将无效
    • 示例\""产生powershell -command " Write-Output \""a & b\"" ";也就是说,a & b不需要转义,但它周围的两个空格都折叠成一个空格。
  • 在所有其他情况下都使用& ,但是您需要分别\"-转义以下{在^中包含cmd.exe的{​​1}}个元字符运行:^ 感谢LotPings

    • 示例\"...\"产生& | < > ^;也就是说,powershell -command " Write-Output \"a ^& b\" "需要与a & b进行转义,但是正确保留了其周围的双倍空格。

    • 另外,按字面意义对待&(以及^%)来说,转义语法取决于您是否从命令调用行批处理文件:使用前者的enabledelayedexpansion!)和%^USERNAME%!^USERNAME / {{1 }}在%%USERNAME%%内运行),请参见this answer了解详细信息。

    • 毋庸置疑,实现以上操作是一项繁琐且容易出错的任务,自动化并非易事。
    • ^!USERNAME^!几乎受所有程序(批处理文件除外)的支持,如果不满足这些额外的转义要求,则使用它的命令行有可能跨不同的平台和shell运行-从PowerShell 调用的明显例外,可悲的是,其中需要附加转义,并且^^!USERNAME^^!中的\"...\"必须以\"的形式转义(原文如此)。

有关避免使用"来缓解逃生疼痛的方法,请参见底部。


其他程序,包括PowerShell Core

  • just "..." 用于使用 Microsoft 编译器编译的程序,在Windows上,< em> Python Node.js 以及PowerShell Core \`"
    遗憾的是,此健壮的选项不能与"一起使用,即 Windows PowerShell

  • "" 用于具有Unix传统的程序,例如Perl和Ruby -带有上面所讨论的令人头疼的问题。


避免嵌入pwsh.exe

也就是说,当您调用PowerShell时,您常常可以不用 嵌入引号

  • 您的字符串中可能有一些根本不需要引号的参数,例如powershell.exe\"

  • 您也可以在整个命令字符串内使用引号("),而无需转义。请注意,从PowerShell的角度来看,此类字符串是字符串 literals

将它们放在一起:

text1.txt

请注意,由于没有必要,我还删除了命令周围的text2.txt


[1] eryksun表示如下:“这是Windows命令行不可避免的挫败感。每个程序都使用所需的规则来解析自己的命令行。因此a的语法命令行不仅必须与外壳程序(CMD)一起使用,而且还必须与在管道中调用的所有程序一起使用。在Unix世界中,外壳程序将命令行解析为'...'数组,因此通常您只需要正确使用语法即可让外壳开心。”
即使在Unix上,PowerShell Core的问题也源于它在传递参数之前如何在后台重新引用参数-请参见this GitHub docs issue