Currently, when I'm looking through a bunch of files for a string in powershell I use the following:
PS: C:\> ls -r | Select-String "dummy" | ls -r
And that lists all files that have that string in them. If I do either
PS: C:\> ls -r | Select-String "dummy" | ls -r | cat
PS: C:\> ls -r | Select-String "dummy" | cat
It will again search through and cat all the files that contain the string, but it all comes out in one chunk like
file 1 line 1
file 1 line 2
file 2 line 1
file 3 line 1
file 4 line 1
But there's no way to tell which line is in which file. Is there a way to have it list something like:
File 1.txt:
file1 line1
file2 line2
File 2.txt:
file2 line1
etc. A one liner would be preferred, but not necessary
Best Answer
One could argue this isn't a one-liner, but it should work in any case ("should" meaning I haven't tested it, but the script should be right):
Expanded, with comments:
And here's a "golfed" version, if you really want it short. This definitely comes closer to qualifying as a "one-liner".
Aside from the obvious use of aliases, collapsing of whitespace, and truncation of parameter names, you may want to note the following significant differences between the "full" versions and the "golfed" version:
Select-String
was swapped to use piped input instead of-InputObject
.-Pattern
parameter name was omitted fromSelect-String
, as use of that parameter's name is optional.-Quiet
option was dropped fromSelect-String
. The filter will still work, but it will take longer sinceSelect-String
will process each complete file instead of stopping after the first matching line.-eq $true
was omitted from the filter rule. When a filter script already returns a Boolean, you do not need to add a comparison operator and object if you just want it to work when the Boolean is true.Write-Output
was omitted. PowerShell will try to do this as a default action if an object is given without a command.If you don't need all the file's properties, and just want the full path on one line before the file contents, you could use this instead: