Powershell 选择使用Out字符串不处理管道对象的字符串

Powershell 选择使用Out字符串不处理管道对象的字符串,powershell,Powershell,我正在执行一个API请求,该请求返回一组数据。在尝试使用Select字符串搜索时,它只会吐出存储在变量中的整个值。这是一个我正在调用api的internet服务器 $return = Invoke-RestMethod -Method GET -Uri $uri -Headers @{"authorization" = $token} -ContentType "application/json" $file = $return.data $file |

我正在执行一个API请求,该请求返回一组数据。在尝试使用Select字符串搜索时,它只会吐出存储在变量中的整个值。这是一个我正在调用api的internet服务器

$return = Invoke-RestMethod -Method GET -Uri $uri -Headers @{"authorization" = $token} -ContentType "application/json" 
$file = $return.data
$file | Out-String -Stream | Select-String -Pattern "word"
这将返回$file的整个值。打印$file看起来与管道输出相同。为什么这不起作用

$file.Gettype表示它是一个system.object,另一个回答是使用Out字符串,但有些东西不起作用

$file.Gettype
IsPublic IsSerial Name                                     BaseType                   
-------- -------- ----                                     --------                   
True     True     String                                   System.Object 
选择字符串输出Microsoft.PowerShell.Commands.MatchInfo对象。在我看来,输出是通过PS引擎或其他东西来突出显示匹配的,但最终它会打印整个匹配字符串

您应该签出Select字符串提供的对象的成员,如下所示:

$file | Out-String -Stream | Select-String -Pattern "word" | Get-Member

   TypeName: Microsoft.PowerShell.Commands.MatchInfo

Name               MemberType Definition
----               ---------- ----------
...
Matches            Property   System.Text.RegularExpressions.Match[] Matches {get;set;}
...
您感兴趣的是Matches属性。它包含了一系列关于比赛的信息。要准确提取所需内容,请查看匹配项的Value属性:

另一种方式:

$file | Out-String -Stream | Select-String -Pattern "word" | ForEach-Object {$_.Matches} | Select-Object -Property Value

Value
-----
word

选择字符串输出Microsoft.PowerShell.Commands.MatchInfo对象。在我看来,输出是通过PS引擎或其他东西来突出显示匹配的,但最终它会打印整个匹配字符串

您应该签出Select字符串提供的对象的成员,如下所示:

$file | Out-String -Stream | Select-String -Pattern "word" | Get-Member

   TypeName: Microsoft.PowerShell.Commands.MatchInfo

Name               MemberType Definition
----               ---------- ----------
...
Matches            Property   System.Text.RegularExpressions.Match[] Matches {get;set;}
...
您感兴趣的是Matches属性。它包含了一系列关于比赛的信息。要准确提取所需内容,请查看匹配项的Value属性:

另一种方式:

$file | Out-String -Stream | Select-String -Pattern "word" | ForEach-Object {$_.Matches} | Select-Object -Property Value

Value
-----
word


仔细检查后,我怀疑您的问题来自文档中的模糊性:

指示cmdlet为命令的每一行发送单独的字符串 输入对象。默认情况下,将累加每个对象的字符串 并作为单个字符串发送

其中单词行应作为项目读取

要将原始字符串拆分为单独的行,需要使用以下命令拆分字符串:

$Lines = $return.data -split [Environment]::NewLine
请注意,这假设您的数据在新行中使用的字符与您使用的系统相同。如果不是这样,您可能希望使用正则表达式拆分行,例如:

$Lines = $return.data -split "`r*`n"
那么Stream参数做什么呢

它为输入对象的每个项发送一个单独的字符串。 其中,在此定义中,为可能的复数输入对象使用单数名称也是已知的常见最佳PowerShell实践

这意味着如果使用上述定义的$Lines变量或类似$Lines=Get Content.\File.json的内容,则输入对象$Lines是字符串的集合:

$Lines.GetType().Name
String[]
如果将此字符串流式处理为Out字符串,默认情况下,它将连接所有项目并返回单个字符串:

($Lines | Out-String).GetType().Name
String
相比之下,如果使用-Stream参数,则它会将$Lines集合中的每个分离项直接传递给下一个cmdlet:

($Lines | Out-String -Stream).GetType().Name
Object[]
我已为此创建了一个文档问题:

注:

总的来说, 包括使用字符串 方法和/或cmdlet,如选择字符串。相反,你应该使用 相关的解析器,例如。 用于搜索和替换,从而简化语法 通常会处理已知的问题和陷阱


仔细检查后,我怀疑您的问题来自文档中的模糊性:

指示cmdlet为命令的每一行发送单独的字符串 输入对象。默认情况下,将累加每个对象的字符串 并作为单个字符串发送

其中单词行应作为项目读取

要将原始字符串拆分为单独的行,需要使用以下命令拆分字符串:

$Lines = $return.data -split [Environment]::NewLine
请注意,这假设您的数据在新行中使用的字符与您使用的系统相同。如果不是这样,您可能希望使用正则表达式拆分行,例如:

$Lines = $return.data -split "`r*`n"
那么Stream参数做什么呢

它为输入对象的每个项发送一个单独的字符串。 其中,在此定义中,为可能的复数输入对象使用单数名称也是已知的常见最佳PowerShell实践

这意味着如果使用上述定义的$Lines变量或类似$Lines=Get Content.\File.json的内容,则输入对象$Lines是字符串的集合:

$Lines.GetType().Name
String[]
如果将此字符串流式处理为Out字符串,默认情况下,它将连接所有项目并返回单个字符串:

($Lines | Out-String).GetType().Name
String
相比之下,如果使用-Stream参数,则它会将$Lines集合中的每个分离项直接传递给下一个cmdlet:

($Lines | Out-String -Stream).GetType().Name
Object[]
我已为此创建了一个文档问题:

注:

总的来说, 包括使用字符串 方法和/或cmdlet,如选择字符串。相反,你应该使用 相关的解析器,例如。 用于搜索和替换,从而简化语法 通常会处理已知的问题和陷阱

为了补充从PowerShell 7.1开始的s-Stream开关的精确逻辑:

把绳子拔出来,就像 其他Out-*cmdlet(如Out File)用于生成其输入对象的人性化表示

如果没有-Stream,Out字符串只会生成一个通常为多行的字符串

对于-Stream,通常会发生逐行输出行为,但恰好是多行字符串的输入对象除外,这些字符串按原样输出

因为这个例外既模糊又无益,建议删除它。 对于所谓的带内数据类型,-Stream的工作方式如下所示,这真正导致逐行输出:

输入对象由PowerShell的丰富格式系统进行格式化,然后组成结果表示的行被逐个输出。 带外数据类型在格式化系统之外单独格式化,只需调用它们的.NET.ToString方法即可

简而言之:表示单个值的数据类型是带外数据类型,除[string]外,带外数据类型还包括[char]和各种标准数字类型,如[int]、[long]、[double]、

[string]是唯一一种本身可以导致多行表示的带外类型,因为对字符串调用.ToString是有效的,没有返回字符串本身(无论是单行还是多行)的操作

因此:

任何字符串(尤其是多行字符串)作为一个整体按原样输出,将其拆分为单独的行需要显式操作;e、 g.请注意,正则表达式\r?\n同时匹配Windows样式的CRLF和Unix样式的LF only换行符:

"line 1`nline 2`nline 3" -split '\r?\n' # -> 'line 1', 'line 2', 'line 3'
如果您的输入对象是带内对象和带外多行字符串的混合体,则可以将带外字符串流与带外拆分相结合;e、 g:

为了补充从PowerShell 7.1开始的s-Stream开关的精确逻辑:

Out字符串与Out File等其他Out-*cmdlet一样,用于生成其输入对象的人性化表示

如果没有-Stream,Out字符串只会生成一个通常为多行的字符串

对于-Stream,通常会发生逐行输出行为,但恰好是多行字符串的输入对象除外,这些字符串按原样输出

因为这个例外既模糊又无益,建议删除它。 对于所谓的带内数据类型,-Stream的工作方式如下所示,这真正导致逐行输出:

输入对象由PowerShell的丰富格式系统进行格式化,然后组成结果表示的行被逐个输出。 带外数据类型在格式化系统之外单独格式化,只需调用它们的.NET.ToString方法即可

简而言之:表示单个值的数据类型是带外数据类型,除[string]外,带外数据类型还包括[char]和各种标准数字类型,如[int]、[long]、[double]、

[string]是唯一一种本身可以导致多行表示的带外类型,因为对字符串调用.ToString是有效的,没有返回字符串本身(无论是单行还是多行)的操作

因此:

任何字符串(尤其是多行字符串)作为一个整体按原样输出,将其拆分为单独的行需要显式操作;e、 g.请注意,正则表达式\r?\n同时匹配Windows样式的CRLF和Unix样式的LF only换行符:

"line 1`nline 2`nline 3" -split '\r?\n' # -> 'line 1', 'line 2', 'line 3'
如果您的输入对象是带内对象和带外多行字符串的混合体,则可以将带外字符串流与带外拆分相结合;e、 g:


这似乎只找到一个匹配项,而不是所有匹配项。使用.matches.value或与ForEach对象一起使用。如果我将数据保存到一个文件中,并从一个文件中读取数据,那么它就可以正常工作。只是不使用变量管道。这似乎只找到一个匹配项,而不是所有匹配项。使用.matches.value或与ForEach对象一起使用。如果我将数据保存到一个文件中,并从一个文件中读取数据,那么它就可以正常工作。只是变量管道不行。你的论点中有一些漏洞,说明它没有按你预期的方式工作。请创建一个示例,并在问题中添加一个$return.data示例,以便我们可以证明它是否有效。您的论点中存在一些漏洞,表明它没有按照您预期的方式工作。请创建一个示例,并在问题中添加一个$return.data示例,以便我们可以证明它是否有效。您的解释非常有用,解决了我的问题。当API返回数据时,每一新行都有一个换行字符。因此,仅使用'n进行拆分就解决了Select字符串只返回一个匹配项或根本不返回匹配项的问题。回答很好,但每个项目的解释不正确-这是关于带内和带外格式的-请参阅我的答案;另外,我建议使用'r?'n或'\r?\n'作为正则表达式。您的解释非常有用,解决了我的问题。当API返回数据时,每一新行都有一个换行字符。因此,仅使用`n进行分离就解决了仅返回Select字符串的问题
e匹配或根本不匹配。答案很好,但每个项目的解释不正确-这是关于带内和带外格式的-请参阅我的答案;此外,我建议使用'r?'n或'\r?\n'作为正则表达式。