【问题标题】:Why does FINDSTR behave differently in powershell and cmd?为什么 FINDSTR 在 powershell 和 cmd 中的行为不同?
【发布时间】:2014-06-01 21:41:00
【问题描述】:

以下命令将echo 的输出通过管道传输到findstr,并尝试匹配正则表达式。我用它来检查回显的行是否只包含(一个或多个)数字:

echo 123 | findstr /r /c:"^[0-9][0-9]*$"

findstr 的预期输出是123,这意味着表达式可以与此字符串匹配。当我使用powershell.exe 执行命令时,输出是正确的。 但是,在cmd.exe 中执行命令不会给出匹配项。它只输出一个空行并将%ERRORLEVEL% 设置为1,这意味着没有找到匹配项。
是什么导致了不同的行为?有没有办法让这个命令也能在 cmd 上正确运行?

我的操作系统是 Windows 7 Professional,64 位。

【问题讨论】:

    标签: regex powershell windows-7 cmd findstr


    【解决方案1】:

    在 Powershell 中,该命令将字符串 123 回显到管道并且与您的正则表达式匹配。

    在 cmd 中,您的命令将 123<space> 回显到管道。正则表达式中不允许使用尾随空格,因此无法匹配。

    试试:

    echo 123| findstr /r /c:"^[0-9][0-9]*$"
    

    它会工作得很好。或者完全切换到 Powershell,而不必担心 cmd.exe 的变幻莫测。

    编辑: 是的,cmd 和 powershell 处理参数的方式非常不同。

    使用 cmd,所有程序都通过一个简单的文本命令行传递。 cmd 执行的处理非常少:它将在|& 终止命令,删除 i/o 重定向并替换任何变量。当然,它也识别命令并执行它。任何参数处理都是由命令本身完成的,因此命令可以选择是空格分隔参数还是" 字符的含义。大多数命令对这些事情有一个相当普遍的解释,但他们可以用他们给出的字符串做他们自己的事情。 echo 做自己的事。

    另一方面,Powershell 具有复杂的参数语法。所有的参数解析都是由 Powershell 完成的。然后将解析的参数作为 .Net 对象序列传递给 Powershell 函数或 cmdlet:这意味着您不仅限于传递简单的字符串。如果该命令结果不是 powershell 命令并在外部运行,它将尝试将对象转换为字符串并在任何有空格的参数周围加上引号。有时转换可能会有点混乱,但这确实意味着这样的事情:

    echo (1+1)
    

    将在 Powershell 中回显 2,其中 cmd 只会回显输入字符串。

    值得始终记住的是,使用 Powershell 您正在处理对象,例如:

    PS C:\> echo Today is (get-date)
    Today
    is
    
    17 April 2014 20:03:15
    
    
    PS C:\> echo "Today is $(get-date)"
    Today is 04/17/2014 20:03:20
    

    在第一种情况下,echo 获得 3 个对象、两个字符串和一个日期。它在单独的行上输出每个对象(类型更改时为空行)。在第二种情况下,它得到一个字符串对象(与 cmd echo 不同,它永远不会看到引号)。

    【讨论】:

    • 谢谢,这确实有效。但是为什么回声的行为会有所不同呢? cmd 处理参数的方式与 powershell 不同吗?
    • @maddin45 添加了一些关于如何处理参数的描述。
    • 哇,我猜 PowerShell 确实名副其实。感谢您的详尽解释!如果可以的话,我会再次投票给这个答案:) 我想我会更多地研究 PowerShell 的功能,这似乎真的很有用。
    猜你喜欢
    • 2020-03-25
    • 1970-01-01
    • 2016-05-20
    • 2021-11-29
    相关资源
    最近更新 更多