问题
I get all the packages installed on my PC using Get-AppxPackage
and I'm trying to find all the matches in that with N lines before and after using Select-String
.
However, the select string is only showing a matches as single line and it's not showing all the matches either. This only happens when I pipe the output from Get-AppxPackage
and not if I write it to a file and then do cat <filename> | select-string ...
.
As you can see in the example below the two results of using pipe and cat
. I'm interested in results like from cat
i.e. detailed info about the app.
So what am I doing wrong here? Why is the output different?
Example (everyone should have MS Edge so I'll use that as an example) :
PS > Get-AppxPackage | Select-String -pattern 'edge' -context 3, 3 -allmatches
Microsoft.Windows.StartMenuExperienceHost_10.0.18362.329_neutral_neutral_cw5n1h2txyewy
Microsoft.Windows.Cortana_1.13.0.18362_neutral_neutral_cw5n1h2txyewy
Microsoft.AAD.BrokerPlugin_1000.18362.329.0_neutral_neutral_cw5n1h2txyewy
> Microsoft.MicrosoftEdge_44.18362.329.0_neutral__8wekyb3d8bbwe
Microsoft.Windows.CloudExperienceHost_10.0.18362.329_neutral_neutral_cw5n1h2txyewy
Microsoft.Windows.ContentDeliveryManager_10.0.18362.329_neutral_neutral_cw5n1h2txyewy
Windows.CBSPreview_10.0.18362.329_neutral_neutral_cw5n1h2txyewy
Microsoft.Windows.Apprep.ChxApp_1000.18362.329.0_neutral_neutral_cw5n1h2txyewy
Microsoft.Win32WebViewHost_10.0.18362.329_neutral_neutral_cw5n1h2txyewy
Microsoft.PPIProjection_10.0.18362.329_neutral_neutral_cw5n1h2txyewy
> Microsoft.MicrosoftEdgeDevToolsClient_1000.18362.329.0_neutral_neutral_8wekyb3d8bbwe
Microsoft.LockApp_10.0.18362.329_neutral__cw5n1h2txyewy
> Microsoft.EdgeDevtoolsPlugin_10.0.18362.329_neutral_neutral_cw5n1h2txyewy
Microsoft.ECApp_10.0.18362.329_neutral__8wekyb3d8bbwe
Microsoft.CredDialogHost_10.0.18362.329_neutral__cw5n1h2txyewy
Microsoft.BioEnrollment_10.0.18362.329_neutral__cw5n1h2txyewy
PS > cat .\appx-packages.txt | select-string -pattern 'edge' -context 3, 3 -allmatches
SignatureKind : System
Status : Ok
> Name : Microsoft.MicrosoftEdge
Publisher : CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US
Architecture : Neutral
ResourceId :
Version : 44.18362.329.0
> PackageFullName : Microsoft.MicrosoftEdge_44.18362.329.0_neutral__8wekyb3d8bbwe
> InstallLocation : C:\Windows\SystemApps\Microsoft.MicrosoftEdge_8wekyb3d8bbwe
IsFramework : False
> PackageFamilyName : Microsoft.MicrosoftEdge_8wekyb3d8bbwe
PublisherId : 8wekyb3d8bbwe
IsResourcePackage : False
IsBundle : False
SignatureKind : System
Status : Ok
> Name : Microsoft.MicrosoftEdgeDevToolsClient
Publisher : CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US
Architecture : Neutral
ResourceId : neutral
Version : 1000.18362.329.0
> PackageFullName : Microsoft.MicrosoftEdgeDevToolsClient_1000.18362.329.0_neutral_neutral_8wekyb3d8bbwe
> InstallLocation : C:\Windows\SystemApps\Microsoft.MicrosoftEdgeDevToolsClient_8wekyb3d8bbwe
IsFramework : False
> PackageFamilyName : Microsoft.MicrosoftEdgeDevToolsClient_8wekyb3d8bbwe
PublisherId : 8wekyb3d8bbwe
IsResourcePackage : False
IsBundle : False
SignatureKind : System
Status : Ok
> Name : Microsoft.EdgeDevtoolsPlugin
Publisher : CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington, C=US
Architecture : Neutral
ResourceId : neutral
Version : 10.0.18362.329
> PackageFullName : Microsoft.EdgeDevtoolsPlugin_10.0.18362.329_neutral_neutral_cw5n1h2txyewy
> InstallLocation : C:\Windows\SystemApps\Microsoft.EdgeDevtoolsPlugin_cw5n1h2txyewy
IsFramework : False
> PackageFamilyName : Microsoft.EdgeDevtoolsPlugin_cw5n1h2txyewy
PublisherId : cw5n1h2txyewy
IsResourcePackage : False
IsBundle : False
回答1:
Select-String
, when given input other than strings, uses simple .ToString()
stringification[1] on each input object before looking for the given pattern.
In your case, the [Microsoft.Windows.Appx.PackageManager.Commands.AppxPackage]
instances output by Get-AppXPackage
stringify to the full package names (e.g., Microsoft.MicrosoftEdge_44.18362.387.0_neutral__8wekyb3d8bbwe
), which explains your output.
In order to make Select-String
search the for-display string representations of objects - as they would print to the console and as they would appear in a file saved to with >
/ Out-File
(cat
is Out-File
's built-in alias on Windows) - you must, surprisingly, use Out-String -Stream
as an intermediate pipeline segment:
Get-AppxPackage | Out-String -Stream | Select-String -Pattern 'edge' -Context 3, 3
Out-String uses PowerShell's formatting system to produce human-friendly display representations of the input objects, the same way that default console output, the Format-*
cmdlets, and >
/ Out-File
do.-Stream
causes the output lines to be sent through the pipeline one by one.
Given that the solution is both non-obvious and cumbersome, it would be nice if Select-String
directly supported this behavior, say via a switch parameter named -FromFormattedOutput
, as detailed in this feature request on GitHub - up-vote the proposal there if you agree.
[1] More accurately, .psobject.ToString()
is called, either as-is, or - if the object's ToString
method supports an IFormatProvider
-typed argument - as .psobject.ToString([cultureinfo]::InvariantCulture)
so as to obtain a culture-invariant representation - see this answer for more information.
来源:https://stackoverflow.com/questions/58730646/select-string-doesnt-show-all-matches-with-get-appxpackage