在上一章中我们讲述了bash基础特性之命令补全和路径补全以及它的命令引用,以及讲了文件管理命令,例如:复制、移动和删除,然后我们也讲述了变量,主要围绕着存储格式、数据范围和参与运算。那么这次我们继续讲述bash的基础特性,这一次我们讲述的是文件的通配符和IO重定向等。

一、globbing:文件名通配

  我们在查询某些文件的时候,通常是在该目录下进行查找,有的时候文件繁多,想找一些特定的文件就得从该目录下逐个匹配进行查找进行通配,如果没找到则显示为空,找到的话就在下面显示该匹配结果的文件或目录,那么我们就需要一个用一些普通字符来赋予它们特殊的意义,比如说在文件系统中匹配单个的,或者匹配整个的,一旦赋予特殊的意义之后,则就不能对其进行普通字符处理,而是用特殊字符来进行字符匹配,这就是globbing文件通配机制,它是对整体文件名进行匹配,而非部分。
  那么glob也有它的匹配模式,刚才我们也谈到过,用一些普通字符来赋予它特殊的意义,用来对文件或目录进行匹配,这就是它的匹配模式,那么匹配模式的示例如下:

  *:匹配任意长度的任意字符;
    pa*, *pa*, *pa, *p*a
    pa, paa, passwd
  ?:匹配指定范围内的任意单个字符
    [a-z], [A-Z], [0-9], [a-z0-9]
     有几种特殊格式:
    [[:upper:]]:所有大写字母;
    [[:lower:]]:所有小写字符;
    [[:alpha:]]:所有字母;
    [[:digit:]]:所有数字;
    [[:alnum:]]:所有的字母和数字;
    [[:space:]]:所有的空白符号;
    [[:punct:]]:所有的标点符号;
  [^]:匹配指定范围外的任意的单个字符;
    [^[:upper:]]
    [^[0-9]]
    [^[:alnum:]]

  那么接下来我们有以下的练习题:
  1、显示/var目录下所有以1开头,以一个小写字母结尾,且中间出现一位任意字符的文件或目录

  # ls /var/1?[[:lower:]]

  2、显示/etc/目录下,以任意数字开头,且非数字结尾的文件或目录

  # ls -d /etc/[[:alnum:]]*[^[:alnum:]]
  # ls -d /etc/[0-9]*[^0-9]

  3、显示/etc目录下,以非字母开头,后面跟着一个字母,以及其它任意字符的文件或目录

  # ls -d /etc [^a-z][a-z]*

  4、复制/etc目录下,所有以m开头,以非数字结尾的文件或目录至/tmp/admin目录

  # cp -r /etc m*[^0-9] /tmp/admin

  5、复制/usr/share/man目录下,所有以man开头,后跟一个数字结尾的文件或目录至/tmp/man目录下

  # cp /usr/share/man/man[[:digit:]] /tmp/man

  6、复制/etc目录下,所有以.conf结尾,且以m,n,r,p开头的文件或目录/tmp/conf.d目录下

  # cp -r /etc [mnrp]*.conf /tmp/conf.d

二、IO重定向及管道

  IO重定向简单来讲就是输入输出重定向,在计算机元器件中,都IO设备,那么就称之为输入输出设备,其实输入输出的设备有很多,其中,显示器是最廉价的一种输出设备,早期的输出是通过打印来输出,不能实时看到结果,后来有显示器可以实时传送,但是输出结果并不能往前翻阅查找,所以IO重定向的功能就是,将默认的输出结果设备重定向到其它的任何的文件或设备当中去。
  我们都知道Linux的哲学思想之一就是一切皆文件,输入和输出设备也是文件,那么可用于输入的设备:文件,分为键盘设备、文件系统上常规文件和网卡等,可用于输出设备也是文件,通常是显示器、文件系统上的常规文件、网卡等。
  那么在程序当中的数据流分为三种:一种是标准的数据流:<-- (符号) 我们称之为标准输入(stdin),通常为键盘设备,另一种是输出的数据流:--> 我们称之为标准输出流(stdout),最常见的就是刚才讲的显示器。还有一种是错误的输出流:--> 我们称为错误输出(stderr),默认也是显示器输出,所以我们可以总结一下:

  程序的数据流有三种:
	输入的数据流: <-- 标准输入(stdin),键盘;
	输出的数据流: --> 标准输出(stdout),显示器;
	错误的输出流: --> 错误输出(stderr),显示器;

  还有就是我们的设备上都有其文件描述符,每一个设备有不同的文件描述符都标识着设备的唯一,输入输出设备也是如此,所以在标准输出设备上标识为0,标准输出标识为1,而错误输出标识为2。

fd:file descriptor,文件描述符
	标准输入:0
	标准输出:1
	错误输出:2

2.1 IO重定向

  如果我们将某一个输出的结果默认显示的设备重定向到另一个设备当中,我们需要使用>,它就是输出重定向,其特性为覆盖输出,还有一种特性是追加输出的重定向,我们使用>>

  输出重定向:>
	特性:覆盖输出;
  输出重定向:>>
	特性:追加输出;

  相对这种特性来说,前者直接覆盖是比较危险,所以请三思后而行,不过我们可以把这个覆盖的特性进行关闭,我们使用set命令就可以。

  # set -C
	禁止覆盖输出重定向至已存在的文件;
	此时可使用强制覆盖输出:>
  # set +C
	关闭上述特性;

  另一种就是错误的输出流重定向,我们在>>>之前都加个2,便成了2>2>>,在上一节我们讲过其文件描述符的错误输出为2,需要注意的是,正确的结果并不会重定向到目标文件或设备中,反之使用输出重定向,其错误结果也不能重定向到目标设备或文件中,都是默认显示。不过我们可以将正确输出和错误输出重定向合并为正常输出流和错误输出流,显示方法如下:

   (1) &>, &>>
   (2) COMMAND > /PATH/TO/SOMEFILE 2&>1
    COMMAND >> /PATH/TO/SOMEFILE 2&>1

  注意:&指的是有当前屏幕输出的结果转移到后台输出。
  还有一种特殊设备在/dev目录下,设备名称叫做null,为空的意思,就是我们将所有数据都重定向到这里的话,无疑于删除,一旦删除就找不到,可以理解为是一个黑洞。
  以上就是输出重定向,还有输入重定向,符号为
<,另一种为<<,我们称之为Here Document,用法如下:

   # cat << EOF
   # cat > /PATH/TO/SOMEFILE << EOF

三、一些常用命令

  我们介绍一下tr命令,tr命令是把输入的字符进行转换,凡是在SET1定义范围内出现的,通通对位转换为SET2出现的字符。它是从标准输入中替换、缩减和(或)删除字符,并将结果写到标准输出。其用法如下:

   用法1:
	# tr [OPTIONS]... SET1 [SET2]
   用法2:
	# tr -d SET1 < /PATH/TO/SOMEFILE
	-d:删除匹配SET1的内容,而不作替换

  需要注意的是:这个命令不修改源文件。

四、管道

  管道是一个命令与命令之间的连接程序,它的原理是将COMMAND1的输出结果通过管道传递到COMMAND2,实现将前一个命令的输出直接定向后一个程序并当作其数据流。用法如下:

   # COMMAND1 | COMMAND2 | COMMAND3

  那么我们接下来说一下tee命令,tee命令就是用来将标准输入的内容输出到标准输出并可以保存其文件。用法如下:

   # COMMAND | tee /PATH/TO/SOMEFILE

  练习1:把/etc/passwd文件前6行的信息转换为大写字符后输出

   # head -n6 /etc/passwd  | tr 'a-z' 'A-Z'