Mathematica allows text searching using regular expressions (based on the PCRE library). It would take some work to re-implement the whole grep
functionality within Mathematica, but for your concrete example
grep -nr -C 2 <pattern>
it is as easy as follows:
ClearAll[Grep]
Grep[files_List, patt_, c_Integer: 0, style : {__} : {Red, Bold}] :=
Monitor[Do[Grep[files[[i]], patt, c, style], {i, Length[files]}],
ProgressIndicator[i, {1, Length[files]}]];
Grep::noopen = "Can't open \"``\".";
Grep[file_, patt_, c_Integer: 0, style : {__} : {Red, Bold}] :=
Module[{lines, pos},
Quiet[Check[lines = ReadList[file, "String"],
Return[Message[Grep::noopen, file], Module]], {ReadList::noopen, ReadList::stream}];
pos = Flatten@Position[StringContainsQ[lines, patt], True];
If[pos =!= {},
Echo@Grid[Prepend[{#,
Column@StringReplace[lines[[Span[Max[# - c, 1], UpTo[# + c]]]],
str : patt :>
"\!\(\*StyleBox[\"" <> str <> "\"," <>
StringRiffle[ToString /@ style, ", "] <> "]\)"]} & /@ pos,
{file, SpanFromLeft}], Dividers -> All, Alignment -> Left]];];
where
file
or files
is a file name/path or a list of them
patt
is a literal string, StringExpression
or RegularExpression
pattern to search for
c
is number of additional lines of leading and trailing output context
style
is a List
of styling directives to be applied to the matching text (I use here great solution by halirutan from this answer); if you don't want to apply a style, put {{}}
as the value for this option
For obtaining the complete listing of files in a directory and all its subdirectories at all levels one can use FileNames
as Select[FileNames[All, dir, Infinity], Not@*DirectoryQ]
. A very enlightening discussion of its usage for obtaining only specific filepaths can be found here.
Examples
Find lines containing the word "Welfare" and display them with 1 surrounding line of leading and trailing context:
Grep[FindFile@"ExampleData/USConstitution.txt",
WordBoundary ~~ "Welfare" ~~ WordBoundary, 1]

Search for word "eye" in all files in a directory and all its subdirectories:
dir = FileNameJoin[{$InstallationDirectory,
"Documentation/English/System/ExamplePages"}];
files = Select[FileNames[All, dir, Infinity], Not@*DirectoryQ];
Grep[files, WordBoundary ~~ "eye" ~~ WordBoundary]
(* during evaluation it displays ProgressIndicator
*)

grep
from WL. Rewriting all the functionality in WL would take a very long time. $\endgroup$