问题
I'm a beginner to powershell and having I suspect what will be a simple problem. I'm trying to do the following command, but it returns nothing as a result and I don't understand why.
I'm trying to get the description of the current section of bcdedit. If I do:
bcdedit /enum | select-string "identifier.*current" -context 0,3
It returns the following:
> identifier {current}
device partition=C:
path \WINDOWS\system32\winload.exe
description Windows 8.1
So why doesn't the following return description Windows 8.1?
bcdedit /enum | select-string "identifier.*current" -context 0,3 | select-string "description"
Instead it returns nothing at all.
Any information on this would be appreciated.
回答1:
You don't get the result you expect, because Select-String doesn't output strings, but MatchInfo objects. If you pipe the output of your first Select-String into the Get-Member or Format-List cmdlet, you'll get something like this:
PS C:\> bcdedit /enum | Select-String "identifier.*current" -Context 0,3 | Get-Member
TypeName: Microsoft.PowerShell.Commands.MatchInfo
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
RelativePath Method string RelativePath(string directory)
ToString Method string ToString(), string ToString(string directory)
Context Property Microsoft.PowerShell.Commands.MatchInfoContext Context {get;set;}
Filename Property string Filename {get;}
IgnoreCase Property bool IgnoreCase {get;set;}
Line Property string Line {get;set;}
LineNumber Property int LineNumber {get;set;}
Matches Property System.Text.RegularExpressions.Match[] Matches {get;set;}
Path Property string Path {get;set;}
Pattern Property string Pattern {get;set;}
PS C:\> bcdedit /enum | Select-String "identifier.*current" -Context 0,3 | Format-List *
IgnoreCase : True
LineNumber : 17
Line : identifier {current}
Filename : InputStream
Path : InputStream
Pattern : identifier.*current
Context : Microsoft.PowerShell.Commands.MatchInfoContext
Matches : {identifier {current}
The Line property contains the actual matching line, and the Context property contains child properties with the pre- and post-context. Since the description line you're looking for is in the PostContext child property, you need something like this for extracting that line:
bcdedit /enum | Select-String "identifier.*current" -Context 0,3 |
Select-Object -Expand Context |
Select-Object -Expand PostContext |
Select-String 'description'
Bottom line: Select-String does work correctly. It just doesn't work the way you expect.
回答2:
Select-String returns MatchInfo objects, not just the string data displayed. That data is taken from the Line and Context properties of the MatchInfo object.
Try this:
bcdedit /enum | select-string "identifier.*current" -context 0,3 | format-list
And you'll see the various properties of the MatchInfo object.
Note that the Context property is displayed as Microsoft.PowerShell.Commands.MatchInfoContext
You'll need to drill down into this object further to get more information:
(bcdedit /enum | select-string "identifier.*current" -context 0,3).context | format-list
There you'll see that the context property is another object with PreContext and PostContext properties, where the actual Pre and PostContext lines are.
So:
(bcdedit /enum | select-string "identifier.*current" -context 0,3).Context.PostContext | Select-String 'description'
Will get the description line from the postcontext matches.
Or you can do this:
[string](bcdedit /enum | select-string "identifier.*current" -context 0,3) -split "`n" -match 'description'
来源:https://stackoverflow.com/questions/21944643/powershell-select-string-not-working-correctly