正则匹配字符

匹配零个或多个字符

星号*能够匹配零个或多个字符。
在 UNIX 系统中,Shell 拥有一个强大的特性:文件名替换。假设你的当前目录下有以下文件:

  1. cat *

Shell会自动将模式*替换成当前目录下能够匹配到的所有文件名。如果你在其他命令中使用*,相同的替换过程一样会发生。
命令行中只要是*出现的地方,Shell都会进行替换:

  1. $ echo * : *
  2. chaptl chapt2 chapt3 chapt4 : chaptl chapt2 chapt3 chapt4

*能够实现部分文件替换功能,它实际上还可以与其他字符配合使用,以限制所能够匹配到的文件名范围。要想只显示出以 chap 开头的文件,可以输入:

  1. cat chap*

匹配单个字符

问号?仅能够匹配单个字符。

  1. $ echo ??*
  2. aa aax alice bb cc report1 report2 report3

??匹配两个字符,*匹配余下的零个或多个字符,其效果就是找出所有文件名长度至少为两个字符的文件。
另一种匹配单个字符的方法是在中括号[]中给出待匹配的字符列表。例如,[abc]能够匹配字符 a、b 或 c。这类似于?,但是允许你选择具体要匹配哪些字符。
你可以使用破折号指定一个字符的逻辑范围。例如,[0-9]能够匹配字符0~9。在指定字符范围的时候,唯一的限制就是第一个字符在字母表上必须位于最后一个字符之前,因此[z-f]并不是一个有效的字符范围,而[f-z]就没有问题。
可以通过配合使用字符范围以及字符列表来实现复杂的替换。例如,[a–np–z]*能够匹配以字母a~n或者p~z开头的所有文件(或者说得再简单些,就是不以小写字母o开头的文件)
如果[之后的第一个字符是!,那么所匹配的内容正好相反。也就是说,匹配中括号内容之外的任意字符。因此:[!a–z]能够匹配小写字母以外的任意字符,另外:*[!o]能够匹配不以小写字母o结尾的那些文件。

标准输入/输出

大多数 UNIX 系统命令都是从屏幕中获得输入,然后将输出结果发送回屏幕。在 UNIX行话中,屏幕通常叫做终端,这一称谓可以追溯到计算机时代的初期。如今,它更多指的是运行在图形化环境(Linux 窗口管理器、Windows 系统或 Mac 系统)中的终端程序。
命令通常从标准输入(默认是计算机键盘)中读取输入。这是一种表明键入信息的不错方法。与此类似,命令通常将输出写入标准输出,这可以是终端或者终端程序(默认)。

f8aeae28-095e-4c74-9b23-392f3e7e8a14.png

如果在调用 sort 命令的时候没有指定文件名参数,那么该命令会从标准输入中获得命令输入。和标准输出一样,默认对应的是终
端(或键盘)。如果采用这种方式输入,必须在完成最后一行输入后指定文件结尾序列(end-of-file sequence),按照 UNIX 的惯例,这指的是 Ctrl+d,即同时按下 Control 键(视所使用的键盘不同,也可以是 Ctrl 键)和 d 键所产生的序列。

输出重定向

很容易就可以将发送到标准输出的命令输出转移到文件中。这种能力叫做输出重定向,也是理解UNIX强大功能必不可少的一环。
如果将> file 放置在能够将输出写入到标准输出上的命令之后,那么该命令的输出就会被写入到文件 file 中:

  1. who > users

如果命令的输出被重定向到某个文件,而这个文件中之前已经有内容存在,那么这些已有内容会被重写。
字符>>表示的另一种类型的输出重定向。这组字符使得命令的标准输出内容被追加到指定文件的现有内容之后。文件中先前的内容并不会丢失,新的输出只不过被添加到了尾部而已。借助于重定向符号>>,你可以将一个文件的内容追加到另一个文件之后:

  1. cat file1 >> file2

输入重定向

正如命令的输出可以被重定向到文件中,文件也可以被重定向到命令的输入中。大于号>作为输出重定向符号,而小于号<则作为输入重定向符号。当然,只有那些从标准输入中接收输入的命令才能够使用这种方法将文件重定向到其输入中。
要想重定向输入,需要将作为输入内容的文件名放在<之后。举例来说,命令wc -l users可以统计出文件users中的行数:

  1. wc -l < users

标准错误

除了标准输入和标准输出,还有第3种虚拟设备:标准错误。绝大多数UNIX命令会将其错误信息写入到这里。和其他两个标准位置一样,标准错误默认是同终端或终端应用程序相关联的。在绝大多数情况下,你无法分辨标准输出和标准错误之间的差别:

  1. $ ls n* #列出所有以 n 开头的文件
  2. n* not found

这里的not found消息实际上就是由ls命令写入到标准错误的。你可以通过重定向ls命令的输出来验证该消息的确没有输出到标准输出:

  1. $ ls n* > foo
  2. n* not found

你可以看到,即便是做了标准输出重定向,这条消息依然出现在了终端,并没有被添加到文件foo中。
上面的例子揭示了标准错误存在的原因:即便是标准输出被重定向到了文件中或通过管道导向了其他命令,错误消息依然能够显示在终端中。你也可以使用一种略微复杂的形式将标准错误重定向到文件中(假如你想在长期的操作过程中记录程序可能出现的错误):

  1. command 2> file

注意,2和>之间可没有空格。所有正常情况下应该进入标准错误的错误信息都会被转入file所指定的文件中,类似于标准输出重定向。

  1. $ ls n* 2> errors
  2. $ cat errors
  3. n* not found

在一行中输入多个命令

如果想在一行中输入多个命令,只需要使用分号作为命令之间的分隔符就行了。举例来说,你可以在同一行中输入 date 和 pwd 命令来显示出当前时间及当前工作目录:

  1. $ date; pwd
  2. Sat Jul 20 14:43:25 EDT 2002
  3. /users/pat/bin

管道

UNIX能够将两个命令连接在一起。这种连接叫做管道,它可以将一个命令的输出直接作为另一个命令的输入。管道使用字符|表示,被放置在两个命令之间。要想在whowc -l之间创建一个管道,可以输入who | wc -l

4406fb9b-d887-4d86-890e-6830c6c6b0b7.jpg
在命令之间建立好管道之后,第一个命令的标准输出就被直接连接到第二个命令的标准输入。

过滤器

UNIX术语中,过滤器常指的是这样的程序:可以从标准输入中接收输入,对输入数据进行处理,然后将结果写入标准输出。说得再简洁些,过滤器就是能够用来在管道中修改其他程序输出的程序。