我尝试从linux bash上的日志文件中grep一个文本。文本在两个方括号内。
e.g。在:
32432423 jkhkjh [234] hkjh32 2342342
我正在搜索234
。
通常应该找到它
\[(.*?)\]
但不是
|grep \[(.*?)\]
使用grep
进行正则表达式搜索的正确方法是什么答案 0 :(得分:4)
您可以查找左括号并使用\K
转义序列清除。然后,匹配结束括号:
$ grep -Po '\[\K[^]]*' <<< "32432423 jkhkjh [234] hkjh32 2342342"
234
请注意,您可以通过以下方式省略-P
(Perl扩展正则表达式):
$ grep -o '\[.*]' <<< "32432423 jkhkjh [234] hkjh32 2342342"
[234]
但是,如您所见,这也会打印括号。这就是让-P
执行后视和后续操作的原因。
您还在正则表达式中提到?
。好吧,正如您已经知道的那样,*?
是以非贪婪的方式进行正则表达式匹配。我们来看一个例子:
$ grep -Po '\[.*?]' <<< "32432423 jkhkjh [23]4] hkjh32 2342342"
[23]
$ grep -Po '\[.*]' <<< "32432423 jkhkjh [23]4] hkjh32 2342342"
[23]4]
.*?
[23]4]
与[23]
匹配.*
。仅使用]
,它与最后[23]4]
匹配,从而获得-P
。此行为仅适用于{{1}}选项。
答案 1 :(得分:1)
[
对shell 和 grep
具有特殊意义,因此您需要引用它两次。反斜杠阻止grep
将它们视为括号表达式的一部分;引用整个事物可以防止shell在将正则表达式传递给grep
之前尝试将其扩展为模式。
... | grep '\[(.*?)\]'
在你的尝试中,贝壳在迫使外壳对它们进行字面处理之后剥去了反斜杠,大约是... | grep '[(.*?)]'
。
答案 2 :(得分:1)
要grep方括号(包括)之间的所有值,您可以使用基于POSIX BRE的grep
命令,例如
grep -o '\[[^][]*]' file
请参见online grep
demo。 -o
选项仅使grep
输出匹配的子字符串,而不是整行,并且\[[^][]*]
模式匹配[
,然后匹配0个或更多出现的字符,但{{1 }}和[
(请参阅否定的]
括号表达式),然后是[^][]*
。
如果需要获取方括号内的值不包含,则可以使用基于PCRE regex的]
命令,如
grep
grep -oP '\[\K[^][]*(?=])' file
模式匹配
\[\K[^][]*(?=])
-一个\[
字符[
-匹配重置运算符,用于将匹配的文本从匹配内存缓冲区中丢弃掉\K
-除[^][]*
和]
以外的0个或更多字符[
-正向超前,需要在当前位置的右侧立即添加一个(?=])
字符。答案 3 :(得分:0)
由于贪婪,我更喜欢\\[[^]]*]
(即\\[ [ ^] ]* ]
,即方括号中的任何 - 但是 - 右方括号<)> \\[.*]
:
$ grep -o \\[.*] <<<"[this] and that too]"
[this] and that too]
VS
$ grep -o \\[[^]]*] <<<"[this] and that too]"
[this]
然后再次grep
不是所有内容的工具(毕竟它是g/re/p
)。如果您只想要方括号内的内容,我会使用sed
:
$ sed 's/.*\[\([^]]*\)].*/\1/' foo
234
即。 替换 - 一切与 - what's功能于括号... SIES 的。