试图理解为什么 grep 手册用一个方括号来声明字符类。
https://www.gnu.org/software/grep/manual/html_node/Character-Classes-and-Bracket-Expressions.html
例如,它指出:使用[:lower:]来匹配小写。然而在终端中,我使用它,结果是:
$ grep [:lower:] test
grep: character class syntax is [[:space:]], not [:space:]
我在尝试使用/理解本手册时遇到了无穷无尽的问题,它有什么问题吗?它似乎只适用于双 [[]],但没有任何解释为什么手册说只使用 [] 代替。
答案1
试图理解为什么 grep 手册用一个方括号来声明字符类。
因为字符类因此只有一组括号。您只需将它们也放入括号表达式中,这意味着最终您有两组。
该手册首先给出了括号表达式的上下文,该表达式周围有括号:
[
括号表达式是由和括起来的字符列表]
。
以下段落假定该上下文。
之内括号表达式,范围表达式由用连字符分隔的两个字符组成。
最后,预定义了某些命名的字符类别之内括号表达式如下。
这两个字符和一个连字符也需要位于括号内,即整个内容是[a-f]
,而不仅仅是a-f
。(*)
字符类也位于括号表达式内,因此例如将字符类[:upper:]
括在括号中以给出括号表达式[[:upper:]]
。或者,如果您在括号内放置多个字符类,则可以使用与[-[:upper:][:digit:]]
破折号、大写字母或数字匹配的字符类。 (一个普通字符和两个字符类位于一个括号表达式中。)
至于为什么语法是这样的,我不知道。
请注意,该手册甚至包含有关如何使用字符类的完整示例:
...例如,
[[:alnum:]]
表示当前语言环境中数字和字母的字符类。
它说:
请注意,这些类名称中的方括号是符号名称的一部分,除了分隔方括号表达式的方括号之外还必须包含方括号。
您收到的错误消息也有描述:
如果您错误地省略了外括号,并搜索例如 ,
[:upper:]
GNU grep 会打印诊断信息并以状态 2 退出,假设您不打算搜索正则表达式[:epru]
。
所以,它看起来确实不像是在告诉整个交易只使用一组括号。
除此之外... 的例子如下[:alnum:]
(并且[:alpha:]
类似):
[:alnum:]
字母数字字符:[:alpha:]
和[:digit:]
;在“C”语言环境和 ASCII 字符编码中,这与[0-9A-Za-z]
.
这是错误的。[0-9A-Za-z]
与 相同[[:alnum:]]
,不是[:alnum:]
。[:alnum:]
会是0-9A-Za-z
,但两者都需要外括号来做任何有用的事情。
当然,错误消息似乎也没有提到字符类和括号表达式之间的区别,所以是的,它们在那里有点不清楚。
请注意,由于括号在 shell 中也是全局字符,因此您应该引用该模式,例如
grep '[[:lower:]]' test
否则,如果存在具有这些确切名称的任何文件,则shell 会将模式扩展为:
、e
、l
、o
、r
或。w
(* 请注意,警告适用于字符范围,它们的解释取决于语言环境,以及 Bash 中的选项globasciiranges
,我认为该选项的行为很奇怪。)