在本教程中,我们将讨论将命令find与正则表达式(regex)一起使用。我们将了解怎样指定正则表达式以进一步优化搜索结果。

正则表达式

在介绍怎样在find中使用正则表达式之前,我们先来了解一下哪些是正则表达式以及正则表达式的构造。

正则表达式(简称regex)是一种功能强悍的工具,由指定搜索模式的字符序列描述。正由于这般,将正则表达式与find结合使用,能够以更精简的命令实现更精细的搜索。

正则表达式有不同的类型和格式。下边解释的概念在它们之间是一致的。不过,更中级的功能须要晓得使用的是哪种类型的正则表达式,由于它们之间存在差别。下文将详尽介绍find命令所接受的regex类型。

主要正则表达式句型和示例

尽管regex有时会让人望而生畏,但它能改进搜索并提高与命令行的交互。只需把握基本知识,我们能够从中受益。

简单介绍一下,regex标记可以匹配多个字符:

依照上面的讨论,.*将匹配除换行符之外的任何字符的零次或多次出现,这意味着它将匹配任何字符串!

命令描述

find命令的使用可分为两个部份:path和expression:

find[path][expression]

path是搜索的目录。expression部份还包括在符合搜索条件的文件中可能采取的操作。在这儿,find命令有三个与正则表达式相关的选项。我们如今通过一些用例示例来展示它们。以下模型目录将用于示例:

$ tree ./
./
├── a0
├── a0.sh
├── A0.sh
├── a1
├── a1.sh
├── A1.sh
├── a2
├── ca
├── cb
├── cc
└── folder
    ├── a0
    ├── a1
    └── a0folder
        ├── a0
        └── a1

使用-regex

第一推荐是使用-regex参数指定正则表达式:

find[path]-regex[regular_expression]

使用该命令将搜索目录文件,并返回符合regular_expression的文件。regular_expression搜索目标涵括了完整的文件名linux find命令 正则 次数,包括根目录。这意味着,假如在当前目录下查找,正则表达式应以./开头(使用反斜杠通配符特殊字符)。

linux正则表达式匹配数字_linuxgrep正则表达式_linux find命令 正则 次数

下边的命令查找当前目录(./)中以字母a开头、后跟0或1的文件(使用-typef标志):

find ./ -type f -regex './a[01].*'
./a1
./a0
./a1.sh
./a0.sh

文件a2没有返回,由于字母a前面没有0或1。我们还可以使用命令在一级目录中搜索,而不是在当前目录中搜索:

find ./ -type f -regex './[^/]*/a[01][^/]*'
./folder/a1
./folder/a0

最后两个regexes有两个不同之处。首先,标记[^/]*/指的是任何不包含任何斜线([^/]*)的字符串,前面紧接着以字母a开头的文件名前的一个斜线(/)。其次,我们用[^/]替换了句号,表示字母a前面不能再出现斜线。

子目录中的文件不符合regex:在第一个斜线(当前目录)和紧随字母a的斜线之间有额外的斜线表示子目录(比如./folder/a0folder/a0)。

最后,要包含所有子目录中的所有文件,我们可以使用

find ./ -type f -regex '.*a[01].*'
./folder/a0folder
./folder/a0folder/a0
./folder/a0folder/a1
./folder/a0
./folder/a1
./a0
./a1
./a0.sh
./a1.sh

使用-iregex

第二种是-iregex:

find[path]-iregex[regular_expression]

该命令执行与-regex选项相同的搜索,但忽视搜索模式的字母大小写。为了易于记忆,命令-iregex代表不分辨大小写的regex。

假如我们更改之前的一条命令,只查找带点的文件(包括[.]),输出结果如下:

find ./ -type f -regex './a[01][.].*'
./a0.sh
./a1.sh

使用-iregex标志而不是-regex标志得到的结果也包括小写字母A的文件:

find ./ -type f -iregex './a[01][.].*'
./a0.sh
./A1.sh
./A0.sh
./a1.sh

使用-regextype

最后,选项-regextype拿来选择正则表达式的类别:

find[path]-regex[regular_expression]-regextype[regex_type]

find命令有不同的regex类型:

上面定义的表达式与所有那些类型的regex都兼容。不过红帽子linux,在不同的regex类型下,更中级的搜索查询可能会形成不同的结果。有一个全面的GNU网页专门详尽介绍了不同的句型。

与BashGlobbing的对比

在使用Linux一段时间后,bash的globbing功能肯定会出现在ls等命令中。让我们瞧瞧下边这条命令:

ls*.png

它会列举扩充名为.png的所有文件。同时,命令:

lsM*.png

列举了扩充名为.png并以字母M开头的所有文件。这就是Bashglobbing的作用:文件名补全。使用find命令搜索文件名时,会用到Bashglobbing。

linux正则表达式匹配数字_linuxgrep正则表达式_linux find命令 正则 次数

虽然它们看上去很相像,但bashglobbing和正则表达式的句型却不尽相同LINUX 删除目录,这促使问题显得愈发复杂。我们将讨论其中两个最相关的差别。在bash中,句点(.)代表一个字面意义上的句点,而在regex中,句点代表任何一个字符。第一条命令展示了bashglobbing:

find ./ -type f -name 'a*.sh'
./a0.sh
./a1.sh

要获得相同的结果,我们可以使用下边的regex查找命令:

find ./ -type f -regex './a.*.sh'
./a0.sh
./a1.sh

bashglobbing与正则表达式的另一个区别是星号(*):在bashglobbing中,星号代表零个或多个任意字符,但在regex中linux find命令 正则 次数,星号代表零个或多个前一个字符。为此,无论是bashglobbing还是regex,类似命令的行为都是不同的。当我们使用bashglobbing时,下边的命令会返回所有以c开头的文件:

find ./ -type f -name 'c*'
./cb
./cc
./ca

然而,假如使用regex类似的搜索模式,则会返回名称中只包含c的所有文件:

find ./ -type f -regex './c*'
./cc

在目录中搜索时,我们应当谨记这种差别,便于更好地使用bash句型或正则表达式。

Author

这篇优质的内容由TA贡献而来

刘遄

《Linux就该这么学》书籍作者,RHCA认证架构师,教育学(计算机专业硕士)。

发表回复