Summary: Learn how to use a powerful Windows PowerShell cmdlet to count words and lines in files, or to count files.
Microsoft Scripting Guy Ed Wilson here. The weekend is halfway over in Charlotte, North Carolina. For my friends in Australia, the weekend is already over, and they are on their way to work. Of course they get to start their weekend earlier than I do. The ideal thing to do is to be in Australia to start the weekend, and then pop back to Charlotte to conclude the weekend. Yes, I have strange thoughts on the weekend. For example, I was on the treadmill earlier, and I was thinking about my favorite Windows PowerShell cmdlet. Anyway, I called the Scripting Wife while I was cooling down. She was downstairs and it is easier to call her than to go down there. Cell phones make great intercoms.
“What are you doing?” she asked as she answered her Windows 7 phone.
“I just finished running on the treadmill, and I am now cooling down. I was wondering what your favorite Windows PowerShell cmdlet is.”
“You have got to be kidding. Why would I have a favorite Windows PowerShell cmdlet?” she asked.
“Well, I was thinking about my favorite Windows PowerShell cmdlet while I was running, and I realized I did not know what yours was,” I said.
“Get-Real,” she said as she hung up.
At times, I think that the Scripting Wife seems to believe I am a nerd. I am not positive of this and am somewhat afraid to ask, but she seems to give off the “nerd alert” vibe when I enter a room or when I call her on her cell phone from upstairs and ask her about her favorite Windows PowerShell cmdlet.
Anyway, I will share my favorite cmdlet—it is the Measure-Object cmdlet. If I did not have the Measure-Object cmdlet, I would need to count the files in a folder manually. This is shown here:
$i=0
Get-ChildItem -Path c:\fso -Recurse -Force |
foreach-object { $i++ }
$i
Using the Measure-Object cmdlet, it is easy to count the files. I merely need to use the following steps.
- Use the Get-Childitem cmdlet to return a listing of fileinfo objects. Use the recurse switch to cause the cmdlet to work through subfolders. The force switch is used to return any hidden or system files. Pass the path to count to the path parameter.
- Pipe the fileinfo objects from step one to the Measure-Object cmdlet
An example of using this command to count the files in the c:\fso folder is shown here:
Get-ChildItem -Recurse -force | Measure-Object
The command and associated output are shown in the following figure. Note that I ran the command twice: the first time without the force switched parameter, and the second time using it.
But the Measure-Object cmdlet does more than just count the number of files in a folder. It can also tell me information about a text file. A sample file is shown in the following figure.
If I want to know how many lines are contained in the file, I use the Measure-Object cmdlet with the line switch. This command is shown here:
Get-Content C:\fso\a.txt | Measure-Object –Line
If I need to know the number of characters, I use the character switch:
Get-Content C:\fso\a.txt | Measure-Object -Character
There is also a words switched parameter that will return the number of words in the text file. It is used similarly to the character or line switched parameter. The command is shown here:
Get-Content C:\fso\a.txt | Measure-Object –Word
In the following figure, I use the Measure-Object cmdlet to count lines; then lines and characters; and finally lines, characters, and words. These commands illustrate combining the switches to return specific information.
One really cool thing I can do with the Measure-Object cmdlet is to measure specific properties of the piped objects. For example, I can use the Get-ChildItem cmdlet to return fileinfo objects for all the text files in the folder. I can examine the length property and find out the minimum length of the files in the folder, the maximum length, the average size, and the total length of all files in the folder. This command and associated output are shown here:
PS C:\fso> Get-ChildItem -Filter *.txt | Measure-Object -Property length -Maximum -Minimum -Average -Sum
Count : 66
Average : 305903.833333333
Sum : 20189653
Maximum : 12534760
Minimum : 0
Property : Length
If I want to, I can pipe the output to a table and create my own custom headings and output. In the following example, I display the average size of the files in kilobytes. I also define the format to omit decimal places:
PS C:\fso> Get-ChildItem -Filter *.txt | Measure-Object -Property length -Maximum -Minimum -Average -Sum | ft count, @{"Label"="average size(KB)";"Expression"={($_.average/1KB).tostring(0)}}
Count Average size(KB)
----- ----------------
66 299
Well, that is about all there to say for now. The Measure-Object cmdlet is one of my favorite cmdlets because it is easy to use and extremely flexible—an unbeatable combination in my book. What is your favorite cmdlet? Add a comment below and let me know. Until tomorrow, see ya.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy