Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recursively find text in files (PowerShell)

I want to find all files in a particular directory that contain a certain string. Specifically, I want to find the carriage return (\r) and then manually go through the files and remove occurrences of it. I don't want PowerShell to remove them because there may be certain subdirectories that require them in my directory structure.

like image 902
user8056359 Avatar asked Jul 29 '17 08:07

user8056359


People also ask

How do I search for a string in multiple files in PowerShell?

Use Get-ChildItem and Select-String Cmdlet to Search a String in Multiple Files and Return the Name of Files in PowerShell. The Get-ChildItem cmdlet displays a list of files and directories present in the specific location.

How do I find recursively in PowerShell?

Use the Get-ChildItem Cmdlet With the -Recurse Switch in PowerShell to Search Files Recursively. The Get-ChildItem cmdlet displays a list of files and directories on the specific location. It does not show empty directories when used with the -Recurse parameter.


2 Answers

Your question seems to boil down to: I want to find all files in a directory that contain the carriage return. Is there any reason why these answers are not adequate?

For example:

This should give the location of the files that contain your pattern:

Get-ChildItem -recurse | Select-String -pattern "dummy" | group path | select name
like image 82
MechtEngineer Avatar answered Sep 22 '22 23:09

MechtEngineer


You could use Select-String to find patterns in a group of files, however this will only search for the pattern within each line of text. It will not work in your case because you want to search for the line separator.

An easier way is to use Get-Content, this convert a file to an array of strings, one item per line. Therefore any file that has a return and a line feed will produce an array with more than one item. Try something like this:

Get-ChildItem -recurse | ? {(Get-Content $_.FullName).count -gt 1}

If your files are quite large and you want to speed it up then add a -TotalCount like this:

Get-ChildItem -recurse | ? {(Get-Content $_.FullName -TotalCount 2).count -gt 1}

This will only find where the return and line feed are together, if you want instances where they could appear on their own then you will need to force Get-Conent to not read the file as an array of string but one big string instead. Something like this:

Get-ChildItem -recurse | ? {[regex]::Matches((Get-Content $_FullName -Raw), '[\r\n]+').Count -gt 0}
like image 33
Dave Sexton Avatar answered Sep 21 '22 23:09

Dave Sexton