Powershell: How can I count the lines of output from a command for each of many files?
exiftool
produces multiple lines of output for each file it processes. I want to invoke it on all the jpgs in a directory, and I want to see how many lines are output for each file. Doing this,
exiftool *.jpg | measure-object -line
gives me the total number of lines of output for all files together, not the number of lines for each file. I also tried this,
exiftool *.jpg | foreach{get-content $_ | measure-object -line}
but that just showed that I don't know how to use Powershell (i.e., I got a lot of error messages). Help?
Solution 1:
Get-ChildItem -Filter *.jpg |
ForEach-Object { (exiftool $_.FullName).Count }
-
Get-ChildItem -Filter *.jpg
outputs file-information objects for each file whose extension is.jpg
in the current directory. -
ForEach-Object
processes each file-information object, accessible via the automatic$_
variable, and passes it to the externalexiftool
program as a full, file-system-native path, via the file-information object's.FullName
property. -
Given that PowerShell emits the lines output by an external programs one by one, which - when collected via
(...)
- amounts to an array of lines[1], you can simply invoke.Count
on that array to get the line count.- That said, at least hypothetically, piping to
Measure-Object
first for output-line counting and then applying.Count
reduces the memory load (because the lines themselves needn't all be collected in memory first), at the expense of execution speed.
- That said, at least hypothetically, piping to
[1] With a single output line, that line is captured as-is, but PowerShell's unified treatment of collections and scalars exposes a .Count
property even on scalars.