shell学习系列(三).通配符
当在使用命令行时,有很多时间都用来查找所需要的文件,shell提供了一套完整的字符串模式匹配规
则,或者称之为元字符,这样就可以按照所要求的模式来匹配文件.还可以使用字符类型来匹配文件名. 1.使用* 使用星号*可以匹配文件名中的任何字符串,在下面的例子中,给出文件名模式app*,它的意思是文
件名以app开头,后面可以跟随任何字符串,包括空字符串: *也可以用在文件名模式的开头,如: ls *.doc 匹配所有以.doc结尾的文件名. *还可以用在文件名的当中,如: ls cl*.sed 用于匹配所有以cl开头,后面跟任何字符串,最后以.sed结尾的文件名. 2.使用? 使用可以匹配文件名中的任何单个字符,如: ls ??R* 文件名以任意两个字符开头,接着是R,后面跟任何字符的文件. ls conf??.log 文件名以conf开头,中间是任意两个字符,最后以.log结尾的文件. ls f??*s 所有以f开头,中间是任意两个字符,后面跟随任意字符串,并以s结尾的文件名. 3.使用[...]和[!...] 使用[...]可以用来匹配方括号[]中的任何字符.在这一方法中,还可以使用一个横杠-来连接两个
字母或数字,以此来表示一个范围. ls [io]* 列出以i或者o开头的文件名 ls log.[0-9]* 匹配所有以log.开头,后面跟随一个数字,然后可以是任意字符串的文件名. ls log.[!0-9]* 表示非数字开头的字符串. 为了列出所有以大写字母开头的文件名,可以用: ls [A-Z]* 为了列出所有以小写字母开头的文件名,可以用: ls [a-z]* 为了列出所有以数字开头的文件名,可以用: ls .*
|
|
|
=====================================================
在shell脚本中,可以用几种不同的方式读入数据:可以使用标准输入,缺省为键盘,或者指定一个文件
作为输入.对于输出也是一样,如果不指定某个文件作为输出,标准输出问题和终端屏幕相关联,也可以
把信息指定到一个文件中.
1.echo
使用echo命令可以显示文本行或变量,或者把字符串输入到文件.它的一般形式为:
echo string
echo命令有很多功能,其中最常用的是下面几个:
\c 不换行
\t 跳格
\n 换行
如果是Linux系统,那么必须使用-n选项来禁止echo命令后换行:
必须使用-e选项才能使转义符生效.
如果希望在echo命令输出之后附加换行,可以使用\n选项.
如果想把一个字符串输出到文件中,使用重定向符号>.
引号是一个特殊的字符,所以必须要使用反斜杠\来使shell忽略它的特殊意义.假设希望使用echo
命令输出这样的字符串: "/dev/rmt0", 那么只要在引号前面加上反斜杠就可以了:
echo "\"/dev/rmt0\""
2.read
可以使用read语句从键盘或文件的某一行文本中读入信息,并将其赋给一个变量.如果只指定了一
个变量,那么read将会把所有的输入赋给该变量,直至遇到第一个文件结束符或回车.
它的一般形式为:
read varible1 varible2
在下面的例子中,只指定了一个变量 ,它将被赋予直至回车之前的所有内容.
read name
hello i am a man
echo $name
hello i am a man
在下面的例子中,给出了两个变量,它们分别被赋予名字和姓氏,shell将用空格作为变量之间的分
隔符.
read name surname
john doe
echo $name $surname
john doe
如果文本域过长,shell将所有的超长部分赋予最后一个变量.
3.cat
cat是一个简单而通用的命令,可以用它来显示文件内容,创建文件,还可以用它来显示控制字符.
在使用cat命令时要注意,它不会在文件分页符处停下来.它会一下显示完整个文件.如果希望每次显示
一页,可以使用more命令或把cat命令的输出通过管道传递到另外一个具有分页功能的命令中.
cat myfile | more
cat命令的一般形式为:
cat [options] filename1 ... filename2
cat命令最有用的选项就是:
-v显示控制字符.
如果希望显示myfile1, myfile2, myfile3这三个文件,可以用:
cat myfile1 myfile2 myfile3
如果希望创建一个名为bigfile的文件,该文件包含上述三个文件的内容,可以把上面命令的输出
重定向到新文件中:
cat myfile1 myfile2 myfile3 > bigfile
4.管道
可以通过管道把一个命令的输出传递给另一个命令作为输入,管道用竖杠|表示,它的一般形式为:
命令1|命令2
5.tee
tee命令作用可以用字母T来形象地表示,它把输出的一个副本输送到标准输出,另一个副本拷贝到
相应的文件中.如果希望在看到输出的同时,也将其存入一个文件,那么这个命令再合适不过了.
它的一般形式为:
tee -a files
其中-a表示追加到文件末尾
在执行某些命令或脚本时,如果希望把输出保留下来,tee命令非常方便.
who | tee who.out
就将who的结果显示给标准输出,同时保存到who.out文件中.
如:
who | tee who.out | awk '{print $1"\t"$2}' | tee -a who.out
6.标准输入,输出和错误
6.1标准输入
标准输入是文件描述符0,它是命令的输入,缺省是键盘,也可以是文件或其它命令的输出.
6.2标准输出
标准输出是文件描述符1,它是命令的输出,缺省是屏幕,也可以是文件.
6.3标准错误
标准错误是文件描述符2,这是命令错误的输出,缺省是屏幕,同样也可以是文件.
7.文件重定向
在执行命令时,可以指定命令的标准输入,输出和错误,要实现这一点就需要使用文件重定向,在对
标准错误进行重定向时,必须要使用文件描述符.但是对于标准输入和输出来说,这不是必需的.
command > filename 把标准输出重定向到一个新文件中
command >> filename 把标准输出重定向到一个新文件中(追加)
command 1> filename 把标准输出重定向到一个文件中
command > filename 2>&1 把标准输出和标准错误重定向到一个文件中
command 2>filename 把标准错误重定向到一个文件中
command 2>> filename 把标准错误重定向到一个文件中(追加)
command >> filename 2>&1 把标准输出和标准错误重定向到一个文件中(追加)
command < filename > filename2以filename文件作为标准输入,以filename2文件作为标准输出
command < filename 以filename文件作为标准输入
command << delimiter 从标准输入中读入,直到遇到delimiter分界符
command <&m 把文件描述符m作为标准输入
command >&m 把标准输出重定向到文件描述符m中
command <&- 关闭标准入
7.1 重定向标准输出
在下面的命令中,把/etc/passwd文件中的用户ID域按照用户名排列,该命令的输出重定向到
sort.out文件中,要提醒注意的是,在使用sort命令的时候,重定向符号一定要离开sort命令两个空格,
否则该命令会把它当作输入文件.
cat passwd | awk -F: '{print $1}' | sort 1>sort.out
可以把很多命令的输出追回到同一个文件中.
ls -l | grep ^d >> file.out
如果希望把标准输出重定向到文件中,可以用>filename.如果希望追加到已有的文件中,那么可以
使用>>filename.如果想创建一个长度为0的空文件,可以用>filename.
7.2 重定向标准输入
可以指定命令的标准输入.
sort < name.txt
在上面的命令中,sort命令的输入是采用重定向的方式给出的.不过也可以直接把相应的文件作为
该命令的参数.
sort name.txt
在发送邮件的时候,可以用重定向的方法发送一个文件中的内容,如:
mail louise < contents.txt
重定向操作符command << delimiter是一种非常有用的命令,通过都被称为"此处"文档.shell将
分界符delimiter之后直至下一个同样的分界符之前的所有内容作为输入,遇到下一个分界符,shell就
知道输入结束了.这一命令对于自动或远程的例程非常有用.可以用任意定义分界符delimiter,最常见
的是EOF.
7.3 重定向标准错误
为了重定向标准错误,可以指定文件描述符2.如:
grep "trident" missiles 2> /dev/null
8.结合使用标准输出和标准错误
一个快速发现错误的方法就是,先将输出重定向到一个文件中,然后再把标准错误重定向到另外一
个文件中.下面给出一个例子:
在审计文件时,其中一个的确存在,而且包含一些信息,而另一个由于某种原因已经不存在了,想把
这两个文件合并到accounts.out文件中.
cat account_qtr.doc account_end.doc 1> accounts.out 2>accoutns.err
现在如果出现了错误相应的错误将会保存在accounts.err文件中.
9.合并标准输出和标准错误
在合并标准输出和标准错误的时候,切记shell是从左至右分析相应的命令的.
cleanup > cleanup.out 2>&1
在上面的例子中,将cleanup脚本的输出重定向到cleanup.out文件中,而且其错误也被重定向到相
同的文件中.
10.exec
exec命令可以用来替代当前shell,换句话说,并没有启动子shell.使用这一命令时任何现有的环
境将会被清除,并重新启动一个shell,它的一般形式为:
shell command
其中的command通常是一个shell脚本.
当这个脚本结束时,相应的会话就可能结束了.exec在对文件描述符进行操作的时候,它不会覆盖
当前的shell.
11.使用文件描述符
可以使用exec命令通过文件描述符打开和关闭文件,在下面的例子中.选用了文件描述符4,下面的
脚本只是从stock.txt文件中读了两行,然后把这两行回显出来.
该脚本的第一行把文件描述符4指定为标准输入,然后打开stock.txt文件,接下来两行的作用是读
入了两行文本,接着,作为标准输入的文件描述符4被关闭.最后line1和line2两个变量所含有的内容都
被回显到屏幕上.
#!/bin/sh
exec 4<&0 0<stock.txt
read line1
read line2
exec 0<&4
echo $line1
echo $line2
=====================================================
shell学习系列(六).grep1.grep grep的一般格式为: grep [选项] 基本正则表达式 [文件] 这里基本正则表达式可为字符串 1.1 双引号引用 在grep命令中输入字符串参数时,最好将其用双引号括起来,例如"mystring".这样做有两个原因,一是以防被误解为shell命令,二是可以用来查找多个单词组成的字符串,例 如"jet plane".如果不用双引号将其括起来,那么单词plane将被误认为是一个文件,查询结果将返回"文件不存在"的错误信息. 在调用变量时,也应该使用双引号,诸如:grep "$MYVAR" 文件名,如果不这样,将没有返回结果. 在调用模式匹配时,应该使用单引号. 1.2 grep选项 常用的grep选项有: -c 只输出匹配行的行数 -i 不区分大小写(只适用于单字符) -h 查询多文件时不显示文件名 -l 查询多文件时只输出包含匹配字符的文件名 -n 显示匹配行及行号 -s 不显示不存在或无匹配文件的错误信息 -v 显示不包含匹配文件的所有行 1.3 查询多个文件 如果要在当前目录下所有.doc文件中查找字符串"sort",方法如下: grep "sort" *.doc 或在所有文件中查询单词"sort it" grep "sort it" * 1.4 行匹配 grep -c "48" data.f grep返回4,表示是有4行包含字符串"48" 1.5 行数 显示满足匹配模式的所有行行数: grep -n "48" data.f 行数输出在第一列,后跟包含48的每一匹配行. 1.6 显示非匹配行 显示所有不包含48的各行: grep -v "48" data.f 1.7 精确匹配 在抽取字符串"48"时,返回结果也可能会返回包含"484", "483"等含有"48"的其它字符串,实际上应精确抽取只包含48"的各行,可以采用如下方式来只提取含有48的项: grep "48\>" data.f 或者是 grep "\<48\>" data.f grep -w "48" data.f 1.8 大小写敏感 缺省情况下,grep是大小写敏感的,如果要查询大小写不敏感的字符串,必须使用-i选项. 2.grep和正则表达式 使用正则表达式使模式匹配加入一些规则,因此可以在抽取信息中加入更多选项,使用正则表达式最好用单引号括起来,这样可以防止grep中使用的专有模式与一些shell命令的 特殊方式相混淆. 2.1 模式范围 假定要抽取代码为484或483的城市位置. grep '48[34]' data.f 2.2 不匹配行首 如果要抽出记录,使其行首不是4或8,可以在方括号中使用^记号,表明查询在行首开始. grep "^[^48]" data.f 如果要使行首不是48,则: grep -v "^48" data.f 2.3 设置大小写 使用-i开关可以屏蔽月份Sept的大小写敏感,也可以用另外一种方式.这里使用[]模式抽取各行包含Sept 和 sept的所有信息. grep "[Ss]ept" data.f 2.4 匹配任意字符 如果抽取以L开头,以D结尾的所有代码,可使用下述方法.因为已知代码长度为5个字符: grp "k...d" data.f 2.5 日期查询 一个常用的查询模式是日期查询,先查询所有以5开始以1996或1998结尾的所有记录.使用模式5..199[6,8].这意味着第一个字符为5,后跟两个点, grep "5..199[6,8]" data.f 2.6 范围组合 必须学会使用[]抽取信息,假定要取得城市代码,第一个字符为任意字符,第二个字符在0到5之间,第三个字符在0到6之间,使用下列模式即可实现: grep "[0-9][0-5][0-6]" data.f 2.7 模式出现机率 抽取包含数字4至少重复出现两次的所有行,方法如下: grep '4\{2,\}' data.f 同样,抽取记录使之包含数字999,方法如下: grep '9\{3,\}' data.f 2.8 使用grep匹配"与"或者"或"模式 grep命令加-E参数,这一扩展允许使用扩展模式匹配,例如,要抽取城市代码为219或216,方法如下: grep -E '219|216' data.f 2.9 空行 结合使用^和$可查询空行,使用-n参数显示实际行数. grep '^$' myfile 2.10匹配特殊字符 查询有特殊含义的字符,诸如$ . ' " * [] ^ | \ + ?,必须在特定字符前加\,假设要查询包含"."的所有行,脚本如下: grep '\.' myfile 或者是一个双引号 grep '\"' myfile 以同样的方式,如果要查询文件名conftroll.conf,脚本如下: grep 'conftroll\.conf' myfile 2.11查询格式化文件名 使用正则表达式可匹配任意文件名,系统中对文本文件有其标准的命名格式,一般最后六个小字字符,后跟句点.接着是两个大写字符.例如,要在一个包含各类文件名的文件 filename.deposit中定位这类文件名,方法如下: grep '^[a-z]\{1,6\}\.[A-Z]\{1,2\}' filename.deposit 2.12查询IP地址 使用[0-9]\{3\}\.[0-9]\{3\}\. 含义是任意数字出现3次,后跟句点,接着是任意数字出现3次,后跟句点. 3.类名 grep允许使用国际字符模式匹配或匹配模式的类名形式. 类 等价的正则表达式 [[:upper:]] [A-Z] [[:lower:]] [a-z] [[:digit:]] [0-9] [[:alnum:]] [0-9a-zA-Z] [[:space:]] 空格或TAB键 [[:alpha:]] [a-zA-Z] 要抽取产品代码,该代码以5开头,后跟至少两个大写字母,使用的脚本如下: grep '5[[:upper:]][[:upper:]]' data.f 如果要抽取以P或D结尾的所有产品代码,方法如下: grep '[[:upper:]][[:upper:]][P,D]' data.f 4.系统grep命令 4.1 目录 如果要查询目录列表中的目录,方法如下: ls -l | grep '^d' 如果在一个目录中查询不包含目录的所有文件,方法如下: ls -l | grep '^[^d]' 要查询其它用户和其它用户组成员有可执行权限的目录集合,方法如下: ls -l | grep '^d.....x..x' 4.2 passwd文件 grep "root" /etc/passwd 上述脚本查询/etc/passwd文件是否包含root字符串. 4.3 使用ps命令 使用带有ps x命令的grep可查询系统上运行的进程,ps x命令意为显示系统上运行的所有进程列表.输出也应包含此grep命令,因为grep命令创建了相应进程,ps x将找到它,在 grep命令中,使用-v选项可丢弃ps命令中的grep进程. ps ax | grep "named" | grep -v "grep" 4.4 对一个字符串使用grep grep不只应用于文件,也可应用于字符串,为此使用echo字符串命令,然后对grep命令使用管道输入. STR="mary joe peter pauline" echo $STR| grep "mary" |
|
|