不需要整行,只需要正则表达式的匹配

Ale*_*x L 27 shell bash grep regex

我只需要从正则表达式中获取匹配项:

$ cat myfile.txt | SOMETHING_HERE "/(\w).+/"
Run Code Online (Sandbox Code Playgroud)

输出必须只是括号内匹配的内容。

不要认为我可以使用grep因为它匹配整行。

请让我知道如何做到这一点。

Ama*_*rus 24

使用中的-o选项grep

例如:

$ echo "foobarbaz" | grep -o 'b[aeiou]r'
bar
Run Code Online (Sandbox Code Playgroud)

  • grep/egrep 的 o 选项仅返回与整个正则表达式匹配的内容,而不是像他要求的那样只返回 () 中的内容。 (11认同)
  • 真悲哀……你知道我为此与 `sed` 反向引用搏斗了多少次吗? (4认同)
  • 然而,无论如何,了解这一点是一件非常好的事情:-) (2认同)
  • @KyleBrandt:要只匹配一个部分(例如:括号),可以用向前看或向后看来标记其余部分: (?<= ) 和 (?= ) (2认同)

DrY*_*Yak 23

2件事:

  • 正如@Rory 所述,您需要该-o选项,因此仅打印匹配项(而不是整行)
  • 此外,您还需要-P选择使用 Perl 正则表达式,其中包括有用的元素,例如Look forward (?= )Look behind (?<= ),这些元素查找部件,但实际上并不匹配和打印它们。

如果您只想匹配括号内的部分,请执行以下操作:

grep -oP '(?<=\/\()\w(?=\).+\/)' myfile.txt
Run Code Online (Sandbox Code Playgroud)

如果文件包含 sting /(a)5667/,grep 将打印 'a',因为:

  • /(被 找到\/\(,但因为它们在后视中, (?<= )所以没有被报告
  • a被匹配\w并因此被打印(因为-o
  • )5667/由 找到\).+\/,但由于它们处于先行状态 (?= ),因此未报告


小智 16

    sed -n "s/^.*\(captureThis\).*$/\1/p"

-n      don't print lines
s       substitute
^.*     matches anything before the captureThis 
\( \)   capture everything between and assign it to \1 
.*$     matches anything after the captureThis 
\1      replace everything with captureThis 
p       print it
Run Code Online (Sandbox Code Playgroud)


DrY*_*Yak 7

因为除了shell之外,您还将问题标记为bash,所以在grep旁边还有另一个解决方案:

Bash 从 3.0 版开始就有自己的正则表达式引擎,使用=~操作符,就像 Perl 一样。

现在,给出以下代码:

#!/bin/bash
DATA="test <Lane>8</Lane>"

if [[ "$DATA" =~ \<Lane\>([[:digit:]]+)\<\/Lane\> ]]; then
        echo $BASH_REMATCH
        echo ${BASH_REMATCH[1]}
fi
Run Code Online (Sandbox Code Playgroud)
  • 请注意,您必须调用它 asbash而不仅仅是sh为了获得所有扩展
  • $BASH_REMATCH 将给出与整个正则表达式匹配的整个字符串,所以 <Lane>8</Lane>
  • ${BASH_REMATCH[1]} 将给出与第一组匹配的部分,因此只有 8