Bash中的正则表达式问题:[^ negate]似乎不起作用


8

当我ls /directory | grep '[^term]'在Bash中执行时,我得到一个常规清单,好像该grep命令被某种方式忽略了。我尝试使用进行相同的操作egrep,尝试使用双引号和单引号将其使用,但没有更好的结果。当我尝试时,ls /directory | grep '^[term]我得到所有以term开头的条目-符合预期。

我已经在一个在线编辑器中试用了此命令,可以在其中测试我的正则表达式,并且可以正常工作。但不是在Bash中。因此它可以在模拟中工作,但不能在现实生活中工作。

我正在使用Crunchbang Linux10。我希望这是足够的信息,并且期待每一个提示,因为未能在这样的基本级别上执行和浪费时间确实令人沮丧!


由于标题中的否定,我感到困惑。您是否要以grepterm开头的行。或者,您是否想对根本不包含term的行进行grep?
伯恩哈德

@Bernhard:我想要一个列表,方括号中没有该词。不必完全是“任期”!据我了解,[^ abc]表示包含a,b或c或其任何组合的任何内容均不应出现在列表中。
erch 2013年

Answers:


12

确定要发生什么吗?在运行时,ls /directory | grep '[^term]'您实际上不是在拼写字母t的字母。这意味着,如果文件名中包含其他字母,则该文件仍会出现在的输出中ls。以以下目录为例:

$ ls
alpha  brave  bravo  charlie  delta

现在,如果我运行,ls |grep '^[brav]'我将得到以下信息:

$ ls |grep '^[brav]'
alpha
brave
bravo

如您所见,我不仅得到了,brave而且bravo我也得到了,alpha因为角色类[]将从该列表中获取任何字母。

因此,如果我运行,ls |grep '[^brav]'我将获得名称中任何地方都不包含brav字符的所有文件。

$ ls |grep '[^brav]'
alpha
bravo
brave
charlie
delta

如果您注意到它包含了整个目录列表,因为所有文件中至少有一个字母未包含在字符类中。

因此,正如Kanvuanza所说,要将grep替换为“ term”(而不是字符),t e r m您应该使用grep -v

例如:

$ ls |grep -v 'brav'
alpha
charlie
delta

另外,如果您不希望使用类中包含任何字符的文件grep -v '[term]'。这样可以避免显示具有任何这些字符的任何文件。(Kanvuanza的答案)

例如:

$ ls |grep -v '[brav]'

如您所见,没有列出文件,因为此目录中的所有文件至少包含该类的一个字母。

附录:

我想补充一点,使用PCRE可以只使用正则表达式来过滤否定表达式。为此,您可以使用称为负前瞻正则表达式的东西:(?!<regex>)

因此,使用上面的示例,您可以执行类似的操作来获得所需的结果,而无需使用grep标志。

$ ls | grep -P '^(?!brav)'
alpha
charlie
delta

要解构该正则表达式,它首先在一行的开头匹配^,然后查找不匹配的字符串,brav之后再跟随。只有alphacharliedelta匹配,因此只有它们打印出来。


1
这意味着,如果文件名中包含其他字母,则该文件仍会出现在ls的输出中。这回答了很多问题!:)因此,目前最好的方法似乎是-v选择。谢谢您的支持!这个问题真的毁了我的下午,您的回答使我的夜晚更加美好!
erch

为+1 negative look-ahead regex
Abhishek Kashyap '18

3

我猜那grep -v旗做你想要的。从手册页

-v, --invert-match
    Invert the sense of matching, to select non-matching lines.

您可以ls /directory | grep -v [term]用来打印任何不匹配的行。


我知道这个选项,但是假设[^ xyz]与[xyz]相反并且在任何情况下都可以工作,我错了吗?我也想避免在这样的基本级别上的任何地方编辑任何设置。当然,使用反向选项和/或编辑设置是一种不错的方法,但是据我所知,这应该可以直接使用。
erch 2013年

我猜你是对的,这是类否定的通用表示法(即,[^abc]但是我很确定grep除了一些标准的(例如[[:^digits:]])之外,不支持类否定。grep对否定的支持是可怕的!
Pedro Lacerda

Grep对否定的支持太可怕了!这是真正锦上添花的提示。我在egrep中也遇到了同样的问题,目前还远远没有使用(至少对我来说似乎是这样)更高级的命令。您能否建议一个可以提供更好结果且减轻头痛的命令?
erch 2013年

@ cellar.dweller,grep对字符类的处理就很好。它只是意味着与您(误)理解的东西完全不同。[abc]装置中的一个abc; [^abc]意味着什么,但上面。这是一个字符。
vonbrand 2013年

@ cellar.dweller:我认为您最大的问题是对正则表达式的误解,尤其是正则表达式中的字符类。
2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.