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 filterGet-Content
reads each line of every file and passes that on in the pipelineWhere-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 itsbegin
block, accumulates the pipeline input to this variable in itsprocess
block and outputs the variable value in itsend
block.- The last
ForEach-Object
line is necessary becauseMeasure-Object
actually outputs an object with aSum
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 theSum
property of thesum
object.