I'm working on a script to output some data from multiple files based on a string search. It outputs the string found followed by the next 6 characters. I can get this to work for an exact location, however I want to search across files inside multiple subfolders in the path. Using the below script I get PermissionDenied errors...
[regex] $pattern = "(?<=(a piece of text))(?<chunk>.*)"
get-content -Path "C:\Temp\*" |
foreach {
if ($_ -match $pattern) {
$smallchunk = $matches.chunk.substring(0,6)
}
}
"$smallchunk" | Out-File "C:\Temp\results.txt
If I change -Path to one of the subfolders it works fine but I need it to go inside each subfolder and perform the get-content.
e.g. look inside..
C:\Temp\folder1\*
C:\Temp\folder2\*
C:\Temp\folder3\*
and so on...
CodePudding user response:
Abraham Zinala's helpful answer is the best solution to your problem, because letting Select-String search your files' content is faster and more memory-efficient than reading and processing each line with Get-Content.
As for what you tried:
Using the below script I get PermissionDenied errors...
These stem from directories being among the file-system items output by Get-ChildItem, which Get-Content cannot read.
If your files have distinct filename extensions that your directories don't, one option is to pass them to the (rarely used with Get-Content) -Include parameter; e.g.:
Get-Content -Path C:\Temp\* -Include *.txt, *.c
However, as with Select-String, this limits you to a single directory's content, and it doesn't allow you to limit processing to files fundamentally, if extension-based filtering isn't possible.
For recursive listing, you can use Get-ChildItem with -Recurse, as in Abraham's answer, and pipe the file-info objects to Get-Content:
Get-ChildItem -Recurse C:\Temp -Include *.txt, *.c | Get-Content
If you want to simply limit output to files, whatever their name is, use the -File switch (similarly, -Directory limits output to directories):
Get-ChildItem -File -Recurse C:\Temp | Get-Content
CodePudding user response:
Following up on boxdog's suggestion of Select-String, the only limitation would be folder recursion. Unfortunately, Select-String only allows the searching of multiple files in one directory.
So, the way around this is piping the output of Get-ChildItem with a -Recurse switch into Select-String:
$pattern = "(?<=(a piece of text))(?<chunk>.*)"
Get-ChildItem -Path "C:\Temp\" -Exclude "results.txt" -File -Recurse |
Select-String -Pattern $pattern |
ForEach-Object -Process {
$_.Matches[0].Groups['chunk'].Value.Substring(0,6)
} | Out-File -FilePath "C:\Temp\results.txt"
If there's a need for the result to be saved to $smallchunk you can still do so inside the loop if need be.
