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-ChildItemfinds all files recursively that match the filterGet-Contentreads each line of every file and passes that on in the pipelineWhere-Objectincludes only lines that match the given RegEx pattern- The
ForEach-Objectline 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-Objectaccumulates all numbers. Internally, it creates a variable in itsbeginblock, accumulates the pipeline input to this variable in itsprocessblock and outputs the variable value in itsendblock.- The last
ForEach-Objectline is necessary becauseMeasure-Objectactually outputs an object with aSumproperty, 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 theSumproperty of thesumobject.
