Shell 模式匹配与正则表达式的出现

Shell 模式匹配与正则表达式的出现

我对 Unix 比较陌生,我偶然发现了一个好奇心。一些 shell 结构(如caseor find)采用模式匹配,但它并不完全是正则表达式。其他命令,如 edsedviawk使用正则表达式进行模式匹配。有人可以列出哪些 shell 命令(内置命令、程序)使用正则表达式,哪些使用其他类型的模式匹配吗?

答案1

case用途球体,这是一个非常简单的类似于正则表达式的模式匹配系统。有些工具,例如find,实际上支持两个都(在本例中通过-name-regex)。但情况更加复杂:有不同的情况口味正则表达式的。有些工具支持一种,有些工具支持多种。您只需检查每个工具和版本组合的man页面或其他参考文档的内容(即使这样也很难弄清楚)。参考列表将是巨大的,我认为这不是一个非常有用的答案。

答案2

我认为使用正则表达式的主要区别在于它们是否需要匹配整个字符串。在casefind和其他一些 bash 命令中,您必须匹配整个字符串,而在sedawk等中grep,您必须匹配字符串的任何部分。除此之外,它们很相似,但当然并不完全相同。

例如,当您在casebash shell 的语句中使用正则表达式时,假定您的正则表达式描述了整个字符串。即(我正在使用例子在这里

case $SERVER in
db-[0-9]+\.host\.com) echo "DB server"
;;
*)echo "Unknown server"
;;
esac

可以看到db-[0-9]+.host.com描述的是字符串,以“db-”开头,然后有一位或多位数字,最后以“.host.com”结尾,所以db-1 .host.com 将匹配,而 xdb-1.host.com 将不匹配。

现在,如果您查看sed,并以类似的方式编写搜索模式

echo "xdb-1.host.com"| sed -nr '/db-[0-9]+\.host\.com/p'

sedcase命令不同,将打印 xdb-1.host.com 行,因为它可以在该字符串中找到搜索模式。因此,我们的想法不是匹配整个字符串,而是找到该模式的任何出现。

类似地,如果您在find命令中使用正则表达式,则整个字符串必须匹配。例如,

find / -regextype sed -regex ".*\.dat"

将找到所有扩展名为 dat 的文件。但如果您尝试使用 进行相同的搜索sed

find / | sed -nr '/.*\.dat/'

它将匹配文件名中包含字符串“.dat”的所有文件。

当然,还有一些细微的语法差异。例如,如果你这样做

find / -name "*.dat"

这也是一种正则表达式,其中*表示“任意数量的任意符号”,但严格意义上的正则表达式你应该写“.*”,其中“.”表示任意符号,* 表示任意数量的“.”类型的符号,因此一起表示任意数量的任意符号。

相关内容