使用 ERE 的 Grep 不会使用 -v 选项过滤行

使用 ERE 的 Grep 不会使用 -v 选项过滤行

我正在尝试使用 grep 中的扩展正则表达式选项从文件中过滤出行首具有以下字符串格式的行。

any-non-space-char:      *

我以为以下命令可以解决问题;但是,它仅打印出通过通配符获取的 2 个文件中的所有行。


~/tmp > cat * | grep -v -E "^\S+:.{6}\*"
hi
test1      blah, blah, blah:      * blah, blah, blah"
test:      * blah, blah, blah:      * blah, blah, blah
sd
hi
temp:      * blah, blah, blah:      * blah, blah, blah"
temp2:     blah, blah, blah:      * blah, blah, blah
sd
~/tmp >

顺便说一句,我将 grep 别名为'grep --color=auto',因此该命令确实正确地突出显示了符合正则表达式的匹配字符串,这些字符串位于上述输出中的test: *第 3 行和temp: *第 6 行。尽管如此,这些匹配的行还是打印在屏幕上,这是我没有想到的。

两个文件的内容:


~/tmp > ls -l
total 8
-rw-rw-r-- 1 pmn ccusers 116 Dec 11 09:22 1
-rw-rw-r-- 1 pmn ccusers 116 Dec 11 09:23 2
~/tmp >

~/tmp > cat 1
hi
test1      blah, blah, blah:      * blah, blah, blah"
test:      * blah, blah, blah:      * blah, blah, blah
sd
~/tmp >

~/tmp > cat 2
hi
temp:      * blah, blah, blah:      * blah, blah, blah"
temp2:     blah, blah, blah:      * blah, blah, blah
sd
~/tmp >

顺便说一句,以下内容与我预期的类似:


~/tmp > cat * | grep -v -E ":.{6}*"
hi
sd
hi
sd
~/tmp >

删除了以下行


test1      blah, blah, blah:      * blah, blah, blah"
test:      * blah, blah, blah:      * blah, blah, blah
temp:      * blah, blah, blah:      * blah, blah, blah"
temp2:     blah, blah, blah:      * blah, blah, blah

(它还删除了上面的第 1 行和第 4 行,这不是我想要的 - 因此这个 grep 命令对我来说不起作用)。

我知道如何让它在 PERL 上工作;但是,由于某些原因,我只能使用 grep、awk 或 sed。

我怎样才能让它工作?


@PsychoData

感谢您的回复。恐怕该命令没有奏效。您的命令返回以下内容

~/tmp > cat * | grep -v -E "^[^\S]+:.{6}\*"  
hi  
sd  
hi  
sd  
~/tmp >

这与我的问题中返回的输出相同grep -v -E ":.{6}*",但这不是我想要的。我想要一个命令来带来以下输出:

hi  
test1      blah, blah, blah:      * blah, blah, blah"  
sd  
hi  
temp2:     blah, blah, blah:      * blah, blah, blah  
sd

恕我直言,您删除了以下几行,因为进行了贪婪匹配,匹配了尽可能多的行 - 正如您所见,直到以下几行^[^\S]+:最右边的“ ” 。*

test1      blah, blah, blah:      * blah, blah, blah"  
test:      * blah, blah, blah:      * blah, blah, blah  
temp:      * blah, blah, blah:      * blah, blah, blah"  
temp2:     blah, blah, blah:      * blah, blah, blah

:顺便说一句,请注意,每对之间正好有 6 个空格*。我认为格式使得这一点很难注意到。

答案1

尝试grep -v -E "^[^\S]+:.{6}\*"

好的。所以我要做的就是告诉它我想要每一行不包含以下模式的内容,并启用扩展表达式:

match the start of a line, then [anything EXCEPT whitespace] at least once,then a colon, then 6 characters, then an asterisk

任何与该模式不匹配的内容都将显示

答案2

在扩展正则表达式中没有办法进行非贪婪匹配。但是,你可以轻松地使用PCRE 函数

$ grep -hvP "^[^\s]+?:\s+\*" *
hi
test1      blah, blah, blah:      * blah, blah, blah"
sd
hi
temp2:     blah, blah, blah:      * blah, blah, blah
sd

您不需要cat这些文件,grep可以直接打开它们。-h选项关闭打印文件名(不cat输入时是必需的),然后-P打开 PCRE。然后,您在行首搜索一个或多个非空格字符^[^\s]+?,后跟一个:,一个或多个空格(\s+),最后是一个*(您需要转义,否则*它将被视为量词)。

相关内容