3

我很难写一个正则表达式放入 grep 以匹配所有包含 foo_bar 的行和所有其他不包含 foo_.* 的行(除了应该仍然匹配的 foo_bar )。

所以给出:

foo_bar Line 1
foo_baz Line 2
Line 3
foo_biz Line 4

我希望第 1 行和第 3 行返回。

请注意,我不能只匹配不匹配 foo_baz 和不匹配 foo_biz,因为 baz 和 biz 可以是很多很多东西。它必须是 foo_.*

4

3 回答 3

3

你需要结合一个正则匹配和一个负匹配所以正匹配 1 为 foo_bar

foo_bar

然后否定匹配 2 对于所有这些不包含 foo_ 使用堆栈溢出很好的解释 正则表达式来匹配不包含单词的行?

^((?!foo_.*).)*$

在替代正则表达式中结合两者

(foo_bar|^((?!foo_.*).)*$)

现在让我们试试::

    $ cat <<EOF | perl -ane ' /(foo_bar|^((?!foo_.*).)*$)/ && print $_'
    > foo_bar 1
    > fee_foo
    > foo bar
    > foo_buz RT
    > fo_foo 1 
    > fo_ foo_bar
    > EOF

foo_bar 1
fee_foo
foo bar
fo_foo 1 
fo_ foo_bar
于 2012-09-19T15:17:54.983 回答
3

在 OS XI 下,对您的输入执行以下命令:

$ grep -P -v '^foo_(?!bar)' test.txt 
foo_bar Line 1
Line 3

请注意:

-P, --perl-regexp
       Interpret PATTERN as a Perl regular expression.
-v, --invert-match
       Invert the sense of matching, to select non-matching lines.
于 2012-09-19T15:24:24.233 回答
0

使用 sed:

sed -n '/foo_bar/p;/foo_/!p' input

这告诉 sed 默认情况下不打印 ( -n) 并在foo_bar匹配或foo_不匹配时打印。

于 2012-09-19T15:19:40.530 回答