我有一个较大的缩小text.json
文件,我需要在其中找到特定的短语dasdhfb347rbf
并打印出周围的短语grep -Eo '.{0,100}dasdhfb347rbf.{0,100}' /dir/text.json
。 100个字符上下文(前导/尾随)。
我已经尝试hawtio.proxyWhitelist
,但它似乎永远都会挂起。
PS。我有一个带有i7 cpu,8GB内存和SSD驱动器的macbook。
答案 0 :(得分:2)
正如Mark Setchell在his answer中指出的那样,您在{
中使用(未转义)}
和.{0,100}
来匹配多达100个字符。需要使用-E
来启用扩展正则表达式(正则表达式);或者,您可以使用转义(使用默认的基本正则表达式):.\{0,100\}
。
但是,两种更正都无法解决您的问题,即 性能问题:要grep
,整个文件 - 因为它是缩小 JSON - 是单行 ,您的特定正则表达式导致执行时间非常长(取决于您的硬件,在使用600MB文件的10+ 分钟的顺序;据推测,您的正则表达式需要大量的回溯)。
按Yreg's answer中的建议使用LC_ALL=C
会略有改进,但不足以产生真正的差异(LC_ALL=C
简化了字符处理,因为每个字节都被假定为是一个ASCII字符。)
切换到文字字符串匹配可大幅提升效果,但grep
支持文字匹配,但不支持报告基于字符的上下文(仅限基于行的)。
因此使用的工具是awk
,它提供了文字字符串匹配和基于位置的子字符串提取功能:
awk -v RS='\3' -v txt='dasdhfb347rbf' -v n=100 '
BEGIN {
getline; s = $0 # read the entire file
while (pos=index(s, txt)) { # loop over matches
len = length(txt) + 2 * n - (pos - n < 1 ? n - pos + 1 : 0)
print substr(s, pos-n, len)
s = substr(s, pos -n + len)
}
}
' text.json
上述情况应该会好得多。
请注意,需要v RS='\3'
才能使BSD Awk立即读取整个文件(-v RS='^$'
通常与GNU Awk和Mawk一起使用,但这不适用于BSD Awk);请注意,此技术依赖于控件字符0x3
不属于文本。
旁注:
答案 1 :(得分:0)
尝试更改区域设置。
LC_ALL=C grep -o…
答案 2 :(得分:0)
我认为你需要在macOS上使用-E
选项来允许使用扩展的正则表达式:
# without "-E", finds nothing
echo abcdefghijk | grep -o ".def.{3}"
# with "-E", finds regex
echo abcdefghijk | grep -Eo ".def.{3}"
cdefghi