windows powershell发现str的行为不正确



我正在json文件中寻找一个搜索字符串:

> type .input.json
[
{"name": "moish"},
{"name": "oren"}
]
> type .input.json | findstr /n /l "`"name`": `"or"
2:    {"name": "moish"},
3:    {"name": "oren"}

为什么会找到moish条目?我错过了什么?

注意:下面引用的行原本是答案的直接部分,但结果是而不是适用于手头的问题,因为问题中的转义是正确的(唯一缺少的是将/c:直接放在字符串之前,使findstr.exe搜索整个(。

请参阅此答案,以便对问题进行更全面的分析。

通过将文本引号加倍来转义:

type input.json | findstr/n/l""name":"or">

……或者可能使用本机PowerShell cmdletSelect-String而不是findstr:

Select-String -LiteralPath input.json -Pattern '"name": "or'

/c:前置到搜索字符串,以便使findstr将其视为单个字符串来搜索

Get-Content .input.json | findstr /n /l /c:"`"name`": `"or" # Note the /c:

请注意使用Get-Contentcmdlet逐行读取文件,type是PowerShell中的内置别名

注:

  • 默认情况下,如果搜索字符串包含空格,则findstr会搜索空格分隔词中任何的出现,即"name""or,导致两行匹配。/c:表示应搜索字符串作为一个完整字符串(默认情况下,作为正则表达式,或作为文字字符串,使用/l(

  • 除了缺少/c:之外,您的搜索字符串是正确的,但您可以通过使用逐字逐句(单引号(字符串('...'(进行简化:

    • ... | findstr /n /l /c:'"name": "or'
    • 遗憾的是,额外的-对嵌入的"字符的转义。无论哪种方式,都是必需的,至少达到PowerShell 7.2.x,即使不应该是必需的
      • 这是由于PowerShell如何将带有嵌入双引号的参数传递给外部程序的长期错误;a-可能选择加入-修复可能会-看看这个答案
      • 如果您使用的是带有名为PSNativeCommandArgumentPassing实验功能的PowerShell的7.2.x版本或7.3预览版本,并且$PSNativeCommandArgumentPassing首选变量设置为'Standard''Windows',则不再需要-转义,因为PowerShell(最终(会为您执行此操作;即findstr /n /l /c:'"name": "or'就足够了

PowerShell替代方案:Select-String:

如Mathias R.Jessen的回答所示,您也可以使用Select-Stringcmdlet,这是findstr.exe的更强大的PowerShell对应程序,尤其是为了避免引用令人头疼的问题(请参阅上文(和潜在的字符编码问题

  • findstr.exe一样,Select-String默认使用正则表达式;使用-SimpleMatch选择文字匹配。

  • findstre.exe不同,默认情况下,Select-String不区分大小写(PowerShell通常是这样(。使用-CaseSensitive使匹配区分大小写。

  • Select-String将匹配行封装在对象中,这些对象包括关于每个匹配的元数据;如果您只对行文本感兴趣,请在PowerShell(Core(7+中使用-Raw,或通过管道连接到Windows PowerShellForEach-Object Line

  • 虽然通过Get-Content从文件中读取的管线可以工作,但它比通过-LiteralPath参数将文件路径作为参数直接传递给Select-String要慢得多(您也可以通过管道将Get-ChildItem获得的文件信息对象传递给它(。

    • 这还有一个额外的优点,即匹配行的显示表示包括文件名和行号(请参阅下文(

因此,相当于您的(更正的(findstr.exe调用:

Select-String -LiteralPath .input.json -CaseSensitive -SimpleMatch -Pattern '"name": "or'
# Alternative:
Get-ChildItem .input.json |
Select-String -CaseSensitive -SimpleMatch -Pattern '"name": "or'

您将在控制台中获得以下输出(注意由文件名和行号组成的输出行前缀(:

input.json:3:  {"name": "oren"}

请注意,这是Select-String为匹配行发射的[Microsoft.PowerShell.Commands.MatchInfo]类型的对象的显示表示。

相关内容

最新更新