问题描述
这个
ls -l /var/log | awk '{print $9}' | grep "^[a-z]*\.log."
输出这个:
alternatives.log.1
alternatives.log.10.gz
alternatives.log.2.gz
alternatives.log.3.gz
alternatives.log.4.gz
alternatives.log.5.gz
alternatives.log.6.gz
alternatives.log.7.gz
alternatives.log.8.gz
alternatives.log.9.gz
apport.log.1
apport.log.2.gz
apport.log.3.gz
但是这个:
ls -l /var/log | awk '{print $9}' | grep "^[a-z]+\.log."
什么都不输出。
为什么?我刚刚将 *
更改为 +
。不是很相似吗?运算符 +
只需要至少一个匹配项,而 *
则需要零个或多个匹配项。
最佳方法
这是因为 grep
(不带任何参数)仅适用于标准正则表达式。 +
是扩展正则表达式的一部分,因此要使用它,您需要使用 grep -E
或 egrep
:
ls -l /var/log | awk '{print $9}' | grep -E "^[a-z]+\.log."
此外,如果您不想使用扩展的正则表达式,您可以这样做:
ls -l /var/log | awk '{print $9}' | grep "^[a-z][a-z]*\.log."
次佳方法
为了详细说明 MiJyns 的答案,”special characters” like + 也适用于标准正则表达式,但您需要使用反斜杠将它们转义。您可能会说,标准正则表达式和扩展正则表达式之间的默认期望是相反的:
在标准正则表达式中,字符默认按字面匹配。例如,在 grep "ab+"
中,+ 是文字 +。例如,正则表达式会找到 “ab+ab”,但不会找到 “abbbb”。要使用 + 的 “special meaning”,您需要对其进行转义。所以 grep "ab\+"
会找到 “abbb”,但不再是 “ab+ab”。因为在最后一个例子中,+ 被解释为量词“一个或多个那个”,在这种情况下是“一个或多个 b”。
在扩展的正则表达式中,情况正好相反。在这里,您需要转义 “special characters” 才能按字面意思处理。所以 grep -E "ab+"
找到了 “abbb”,但没有找到 “ab+ab”。如果你转义 +,它会按字面意思匹配。所以 grep -E "ab\+"
找到了 “ab+ab”,但没有找到 “abbb”。