using powershell select-string creatively…
this came up yesterday. i thought it was cool enough to blog. i’m sure this is pretty elementary for most of you.
background
i was trying to find a way to search a list of files for content and pull back some attributes along with the search. the problem is once you pass objects from get-childitems through select-string, the type changes.
looking at the object type
let’s look at the type before we send it through select-string:
PS C:\data\temp> ls | gm -MemberType property
TypeName: System.IO.FileInfo
Name MemberType Definition
---- ---------- ----------
Attributes Property System.IO.FileAttributes Attributes {get;set;}
CreationTime Property System.DateTime CreationTime {get;set;}
CreationTimeUtc Property System.DateTime CreationTimeUtc {get;set;}
Directory Property System.IO.DirectoryInfo Directory {get;}
DirectoryName Property System.String DirectoryName {get;}
Exists Property System.Boolean Exists {get;}
Extension Property System.String Extension {get;}
FullName Property System.String FullName {get;}
IsReadOnly Property System.Boolean IsReadOnly {get;set;}
LastAccessTime Property System.DateTime LastAccessTime {get;set;}
LastAccessTimeUtc Property System.DateTime LastAccessTimeUtc {get;set;}
LastWriteTime Property System.DateTime LastWriteTime {get;set;}
LastWriteTimeUtc Property System.DateTime LastWriteTimeUtc {get;set;}
Length Property System.Int64 Length {get;}
Name Property System.String Name {get;}
now after select-string:
PS C:\data\temp> ls | Select-String marcus | gm -MemberType property
TypeName: Microsoft.PowerShell.Commands.MatchInfo
Name MemberType Definition
---- ---------- ----------
Context Property Microsoft.PowerShell.Commands.MatchInfoContext Context {get;set;}
Filename Property System.String Filename {get;}
IgnoreCase Property System.Boolean IgnoreCase {get;set;}
Line Property System.String Line {get;set;}
LineNumber Property System.Int32 LineNumber {get;set;}
Matches Property System.Text.RegularExpressions.Match[] Matches {get;set;}
Path Property System.String Path {get;set;}
Pattern Property System.String Pattern {get;set;}
retrieving the original attributes
as you can see, after sending it through select-string, it converts the type from FileInfo to MatchInfo. as long as i only care about the properties i can use from matchinfo, that’s not really a problem. as noted here:
PS C:\data\temp> ls | Select-String marcus | ft filename, line -auto Filename Line -------- ---- machinelist.txt MARCUS
that becomes a problem since the original attributes aren’t maintained. for example, let’s say i want to pull back the creation time of the file. this illustrates the problem:
PS C:\data\temp> ls | Select-String marcus | ft filename, line, {$_.creationtime} -auto Filename Line $_.creationtime -------- ---- --------------- machinelist.txt MARCUS
if we embed a command, we can retrieve the item again and then pull back the property of it.
PS C:\data\temp> ls | Select-String marcus | ft filename, line, {(ls $_.filename).creationtime} -auto Filename Line (ls $_.filename).creationtime -------- ---- ----------------------------- machinelist.txt MARCUS 4/16/2009 1:45:10 PM
shout out
lots of thanks to shay levy and hal rottenberg for their incredibly rich powershell knowledge.
Comments
Post a Comment