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

Time:07-23

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

CodePudding user response:

Here is a possible solution:

$pattern = 'eggs'

$sum = Get-ChildItem . -File -Recurse -Filter *.txt | 
       Get-Content | 
       Where-Object { $_ -match $pattern } |
       ForEach-Object { [int] ($_ -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]. Then it converts the string into an actual number using cast operator [int], so we can use it for calculations.
  • Measure-Object accumulates all numbers. 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.
  • Related