Powershell script to sum only specific records from file(s)

Viewed 50

I am trying to work with a directory full of files.

I want to find specific rows within the file, from those rows, extract a numeric value and them sum up all these values, for all values, in a directory.

It would look like this...

File1.txt
bread:123
ham:456
eggs:789

File2.txt
bread:999
mayo:789
eggs:123

and so on...

I want to find the row with eggs, extract the number, and sum these numbers together across files.

I found this script from other posts but it's only segements, I still have trouble understanding how to use and pipe/ variables /braces.

dir . -filter "*.txt" -Recurse -name | foreach{(GC $_).Count} | measure-object -sum
#?
Get-Content | Select-String -Pattern "eggs*"
#?
$record -split ":"

I want the script to say "eggs = 912" which would be 123 + 789 = 912

2 Answers

Here is a possible solution:

$pattern = 'eggs'

$sum = Get-ChildItem . -File -Recurse -Filter *.txt | 
       Get-Content | 
       Where-Object { $_ -match $pattern } |
       ForEach-Object { ($_ -split ':')[1] } |
       Measure-Object -Sum |
       ForEach-Object Sum

"$pattern = $sum"

Output:

eggs = 912
  • Get-ChildItem finds all files recursively that match the filter
  • Get-Content reads each line of every file and passes that on in the pipeline
  • Where-Object includes only lines that match the given RegEx pattern
  • The ForEach-Object line splits the line at : and extracts the sub string, which is at array index [1].
  • Measure-Object accumulates all numbers (it converts strings to double, if necessary). Internally, it creates a variable in its begin block, accumulates the pipeline input to this variable in its process block and outputs the variable value in its end block.
  • The last ForEach-Object line is necessary because Measure-Object actually outputs an object with a Sum property, but we only want the value of that property, not the entire object. If you'd remove that line you'd have to write "$pattern = $($sum.Sum)" instead, to access the Sum property of the sum object.

You can treat the as csv files. import-csv doesn't take wildcards for the filename.

import-csv file1.txt,file2.txt -Delimiter : -Header item,amount | 
  where item -eq eggs | measure -sum amount

Count             : 2
Average           :
Sum               : 912
Maximum           :
Minimum           :
StandardDeviation :
Property          : amount
Related