With GNU grep
:
N=10; grep -roP ".{0,$N}foo.{0,$N}" .
Explanation:
-o
=> Print only what you matched
-P
=> Use Perl-style regular expressions
- The regex says match 0 to
$N
characters followed by foo
followed by 0 to $N
characters.
If you don't have GNU grep
:
find . -type f -exec \
perl -nle '
BEGIN{$N=10}
print if s/^.*?(.{0,$N}foo.{0,$N}).*?$/$ARGV:$1/
' {} \;
Explanation:
Since we can no longer rely on grep
being GNU grep
, we make use of find
to search for files recursively (the -r
action of GNU grep
). For each file found, we execute the Perl snippet.
Perl switches:
-n
Read the file line by line
-l
Remove the newline at the end of each line and put it back when printing
-e
Treat the following string as code
The Perl snippet is doing essentially the same thing as grep
. It starts by setting a variable $N
to the number of context characters you want. The BEGIN{}
means this is executed only once at the start of execution not once for every line in every file.
The statement executed for each line is to print the line if the regex substitution works.
The regex:
- Match any old thing lazily1 at the start of line (
^.*?
) followed by .{0,$N}
as in the grep
case, followed by foo
followed by another .{0,$N}
and finally match any old thing lazily till the end of line (.*?$
).
- We substitute this with
$ARGV:$1
. $ARGV
is a magical variable that holds the name of the current file being read. $1
is what the parens matched: the context in this case.
- The lazy matches at either end are required because a greedy match would eat all characters before
foo
without failing to match (since .{0,$N}
is allowed to match zero times).
1That is, prefer not to match anything unless this would cause the overall match to fail. In short, match as few characters as possible.
grep
on JSON documents, you use a JSON parser such asjq
. I assume that the lines are long because the JSON format does not require newlines between values or keys. Parsing out a key's value would presumably be what you want to do, which is the most basic operation a JSON processor can do. – Kusalananda Nov 24 '22 at 07:11