我正在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-Content
cmdlet逐行读取文件,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-String
cmdlet,这是findstr.exe
的更强大的PowerShell对应程序,尤其是为了避免引用令人头疼的问题(请参阅上文(和潜在的字符编码问题。
与
findstr.exe
一样,Select-String
默认使用正则表达式;使用-SimpleMatch
选择文字匹配。与
findstre.exe
不同,默认情况下,Select-String
不区分大小写(PowerShell通常是这样(。使用-CaseSensitive
使匹配区分大小写。Select-String
将匹配行封装在对象中,这些对象包括关于每个匹配的元数据;如果您只对行文本感兴趣,请在PowerShell(Core(7+中使用-Raw
,或通过管道连接到Windows PowerShell的ForEach-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]
类型的对象的显示表示。