Prof. Powershell

How Do You Measure Up?

Measure-Object cmdlet has some interesting properties, but it's up to us to figure out how to use them creatively.

If you've been reading Prof. PowerShell for a while, I'm sure you've seen a few examples of Measure-Object in action. This cmdlet can do a number of calculations:

PS C:\> dir c:\work | Measure-Object -Property Length -Sum -Average

Count    : 33
Average  : 2616247.3030303
Sum      : 86336161
Maximum  :
Minimum  :
Property : Length

In my Work folder, Measure-Object used the Length property of all the file objects and I can see that I have 33 files as well as the average and total sizes in bytes. But Measure-Object can also give you stats on the contents of a file.

This will only work with text files, but if you have any type of log file you might want to know how many words or lines it contains.

PS C:\> get-content c:\work\r.txt | measure-object -Word -Line -Character | format-list

Lines      : 7
Words      : 55
Characters : 833
Property   :

I used Get-Content to retrieve the contents of a text file, c:\work\r.txt, and piped it Measure-Object. Instead of using the numeric properties like -Sum, I use the text-oriented ones like -Line and -Word. The results are self-explanatory.

Unfortunately, the cmdlet insists on writing the “Property” which is sort of silly because it is irrelevant in this context. A cleaner, albeit longer, approach is to pipe to Select-Object.

PS C:\> get-content c:\work\r.txt | measure-object -Word -Line -Character | Select Words,Lines,Characters

Words     Lines     Character
-----     -----     ---------
   55         7            83

One interesting behavior when using this with multiple files is that you can end up with total for all files. I have several text files in my Work directory. When I get the content for all those files, Measure-Object returns a value that represents the sum:

PS C:\work> (dir *.txt | get-content | measure-object -word).words 952

Thus, the total number of words in all my text files is 952. If you want individual counts, you'll need to use ForEach-Object:

PS C:\work> dir *.txt | foreach {$_.name; (get-content $_ | measure-object -word).words}
asset-demo.txt
24
computers.txt
5
eventlog-demo.txt
184
file-disk-demo.txt
190
LocalAdmin-demo.txt
105
pipelinedemo.txt
91
r.txt
55
service-demo.txt
208
stats.txt
90

If you come up with a killer use for this concept, I'd love to hear about it.

About the Author

Jeffery Hicks is an IT veteran with over 25 years of experience, much of it spent as an IT infrastructure consultant specializing in Microsoft server technologies with an emphasis in automation and efficiency. He is a multi-year recipient of the Microsoft MVP Award in Windows PowerShell. He works today as an independent author, trainer and consultant. Jeff has written for numerous online sites and print publications, is a contributing editor at Petri.com, and a frequent speaker at technology conferences and user groups.

comments powered by Disqus
Most   Popular