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.