使用GNU grep
:
N=10; grep -roP ".{0,$N}foo.{0,$N}" .
说明:
-o
=>仅打印您匹配的内容
-P
=>使用Perl样式的正则表达式
- 正则表达式表示将0匹配到
$N
字符,foo
然后将0 匹配到$N
字符。
如果您没有GNU grep
:
find . -type f -exec \
perl -nle '
BEGIN{$N=10}
print if s/^.*?(.{0,$N}foo.{0,$N}).*?$/$ARGV:$1/
' {} \;
说明:
由于我们不能再依赖于grep
GNU了grep
,因此我们利用它find
来递归搜索文件(-r
GNU 的操作grep
)。对于找到的每个文件,我们执行Perl代码段。
Perl开关:
-n
逐行读取文件
-l
删除每行末尾的换行符,然后在打印时放回
-e
将以下字符串视为代码
Perl片段的功能与基本上相同grep
。首先,将变量设置$N
为所需的上下文字符数。这BEGIN{}
意味着在执行开始时仅执行一次,而不对每个文件中的每一行执行一次。
如果正则表达式替换有效,则为每行执行的语句将打印该行。
正则表达式:
- 匹配任何旧事物懒洋洋地1处行的开始(
^.*?
),然后.{0,$N}
作为grep
的情况下,随后foo
紧接着又.{0,$N}
终于懒洋洋地匹配任何旧事物,直到行结束(.*?$
)。
- 我们用代替
$ARGV:$1
。$ARGV
是一个神奇的变量,用于保存正在读取的当前文件的名称。$1
括号匹配的是什么:在这种情况下是上下文。
- 两端都需要延迟匹配,因为贪婪的匹配会先吃掉所有字符,然后
foo
再匹配(因为.{0,$N}
允许匹配零次)。
1 也就是说,最好不要匹配任何东西,除非这会导致整体匹配失败。简而言之,请尽可能少地匹配字符。