在Unix操作系统中有一组特殊的字符,它们叫做通配符。通过这些通配符,可以提高某些命令的使用效率。如现在在系统中的某个文件夹下,有test、test1、test2、test3、log、buildlog等文件。但是现在系统工程师只想对以test开头的文件进行操作,如想把它们复制到另外一个文件夹中去。如果没有通配符的情况下,则系统工程师不得不在在cp命令后面把所有的文件名都带上。当文件比较多时,这个操作显然是比较浪费时间的。现在在通配符的帮助下,这项工作将变得很简单。
在Unix操作系统中,把用来构造文件名匹配模式的元字符叫做通配符。在Unix操作系统中,其通配符的功能是比较强大的。那么我们系统工程师可以利用通配符来实现哪些功能呢?在通配符使用过程中又需要注意哪些内容?笔者在接下去的文章中,将会对此进行详细的阐述。
通配符*与通配符?是系统工程师使用的最频繁地两个通配符。如在对数据库进行异地备份的使用就需要用到这个通配符。如笔者前不久在Unix操作系统上部署了一个Oracle数据库系统,然后采用expdb工具导出数据库进行备份。但是利用这个工具在对数据库进行备份的时候,其用到的转储文件不只一个。如在数据库部署的时候,如果把这个转储文件的大小设置为1000M。而数据库的大小为5000M时,则最后的转储文件大小可能就有5个。如笔者把这个转储文件的名字设置为backup_%U.dmp的话,则其生成的转储文件的名字就为backup_01.dmp、backup_02.dmp等等。随着数据库容量的增加,这个转储文件的数量也会随之增加。为此当需要编写一个脚本,把备份在本地的转储文件复制到其他地方时,就不能够使用固定的文件名字了。而需要依靠这个通配符的作用。
如我们可以把这些转储文件表示为*、backup*、backup_??.bmp等等。虽然它们最后都能够完成上面这个任务,但是其仍然有很大的差异。如*表示某个目录下面的所有文件名。如在上面这个需求中,如果除了这些转储文件外,还可能有每次备份的日志文件等等。那么使用单颗*通配符的话,不仅会将转储文件复制到其他地方,而且也会将这个目录下的其他文件如日志文件,也同时复制过去。显然,如果在这个目录下,由许多跟转储文件无关的文件时,而且容量比较大,那么在复制过程中就会占用比较多的时间。这是不值得的。为此还需要选择使用一些更加精确的通配符。
那么如果使用backup*表示什么意思呢?如果使用字符串加*通配符,则表示文件名前面几个字符必须为backup,后面字符任意的文件。以上面这个需求为例,只要文件名中前面几个字符为backup的,则相关的文件都符合要求,都会被复制过去。但是,这也有一个问题。如在当前目录中,还有文件名为backup.txt的备份日志文件,那么也同时会给复制过去。而现在系统工程师只需要复制转储文件,这显然跟我们的愿望是违背的。因为我们只需要复制转储文件。
为了最精确的定义某类文件,我们就需要使用?通配符。如上面这个需求,我们要定义符合条件的转储文件,则只需要使用backup_??.dmp即可。他表示名文件名字必须以backup_开头,后面接两个字符,最后以.dmp扩展名结尾的文件。必须一五一十的符合这个规则,否则的话,文件就不会被复制。显然,根据上面这个需求,符合这个条件的就只有转储文件而已。
从上面这个案例中,我们可以看到通配符*与通配符?有本质上的差别。通配符* 表示任意个字符,包括空格字符。如果单个*号的话,表示当前目录下的所有文件;如果前面跟上字符串的话,则表示以这个字符串开头的文件。如果使用通配符?号的话,则表示单个字符。
二、不常用的通配符。
除了以上这两个通配符之外,在Unix操作系统中还有其他一些通配符。虽然这些通配符不怎么用,但是在一些特别的场合中仍然可以起到画龙点睛的作用。如通配符[abc]则表示三个字符中的任何一个字符;如通配符[a-z]则表示所有小写的英文字符。另外在需要的时候,还可以利用!运算符,如[!abc],则表示除a、b、c字符外的任何一个字符等等。这些通配符主要用来实现更加精确的限制。有时候在脚本程序中实现比较严格的控制往往可以提高很好的作用。
三、通配符的使用注意事项。
虽然通过使用通配符,可以提高我们的工作下效率。但是通配符毕竟跟其他字符不同,如果使用的不好的话,是会闯祸的。特别是跟一些删除、重命名等破坏性命令一起使用的时候,更加需要注意通配符使用过程中的一些禁忌。具体的来说,笔者认为在Unix操作系统中使用通配符的禁忌主要包括如下几个方面。
首先是需要注意空格符的影响。如rm *.txt 与rm * .txt两个命令,他们有什么区别呢?从形式上,一下子看不出有多大的区别。不过仔细一看,我们可以看到第二个命令在通配符*号与扩展名.txt中间多了一个空格。虽然这只是一个很小的差异,但是Unix操作系统在处理的时候,可是会相差很大的。系统工程师或者用户本来想使用rm *.txt命名来删除当前目录下的所有txt文件;但是结果使用了rm * .txt命令(可能是在输入的过程中不小心在通配符*号后面多按了一个空格符)。此时操作系统会把当前文件夹下的所有文件都删除。也就是说,如果在通配符*后面有一个空格的话,则其就会忽略空格后面的文本,而表示当前目录下的所有文件。为此在使用*通配符(其他通配符也一样),一定要注意这个空格特殊字符的影响。特别是在使用这些rm命令的时候,最好还是通过交互性的方式执行。如此可以确保操作操作的文件正是用户所想操作的目标文件。从而防止因为错误的命令导致数据被删除,信息被修改等等难以挽回的损失。
其次需要注意不同版本之间对于通配符的支持度是不同的。如通配符[!abc]或者通配符[abc]在c shell下就是不能够识别的。所以如果在编写脚本程序的时候,要尽量少用这些通用性不好的通配符。因为这对脚本程序的移植性不利。所以在编写脚本程序时,能够使用*或者?等通配符的,就使用这些通配符。因为这些通配符基本上每个shell都是支持的。为此在脚本程序移植的过程中,就不会遇到兼容性的问题。不过要了解的是,通配符*号与通配符?号能够表示多个字符或者单个字符,而不能够对字符的范围进行进一步的限制。但是像[abc]等等通配符形式却可以实现精确的限制。所以系统工程师在使用通配符的时候,仍然需要根据用户的需求来选择。如果非要采用这些通配符的话,那么最好能够在脚本程序的注释中添加相关的说明。方便下次脚本程序移植时能够一目了然的知道这个情况,及时调整策略。
第三需要注意通配符*与通配符/号使用的两个限制。在使用ls * 命令显示当前目录下的所有文件时,其是不会显示以点号开头的文件。因为这类文件,在Unix操作系统中表示的是隐藏文件。出于保护的目的,默认情况下不会显示这些隐藏文件(以.号开头的文件)。如果系统工程师要想显示文件的话,则必须在通配符前面输入.号。其次这些通配符不能够代表目录中的/ 符号。也就是说,如果使用cd目录加通配符进行路径切换的话,则这个路径中不能够利用通配符来代表/符号。
从以上的分析中可见虽然通配符提高了我们的办公效率里,但是在使用时或多或少仍然有一些限制。作为系统工程师,要把这些限制牢记于心。无论是在编写脚本程序,还是结合其他命令使用时,需要遵守这些使用过程中的禁忌。