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 external exiftool 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.

[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.