一.sed编辑器
shell脚本最常见的用途就是处理文本文件,sed和gawk能够极大的简化需要进行的数据处理任务。sed编辑器是流编辑器,跟普通交互式文本编辑器(如vim)不同。流编辑器在编辑器处理数据前基于预先提供的一组规则来编辑数据流。由于命令都是一行一行顺序处理,sed编辑器必须一次就完成对文本的修改,所以比交互式编辑器速度快很多。
使用sed命令的格式:$ sed optioons script file
1.替换标记
s命令帮助我们用斜线间制定的第二个文本字符串代替地一个文本字符串,举一个简单的例子:
# echo This is a dog | sed 's/dog/big dog/' This is a big dog
在sed命令行上执行多个命令时,用-e选项:
# echo This is a white dog | sed -e 's/white/black/; s/dog/cat/' This is a black cat
如果有大量sed命令,可以放入一个文件内,用-f选项制定文件,此时不需要用分号:
$ cat script s/white/black s/dog/cat
2.使用地址
默认情况下,sed编辑器中使用的命令会作用与文本数据的所有行。如果只想将命令作用于特定某行或者某些行,需要用行寻址。
sed有两种行寻址:行的数字范围;用文本模式过滤出某行。
例如要替换一个文件data中第二行的某个单词,可以这样:
$ sed '2,3s/dog/cat/'
3.删除行
删除命令d经常和指定地址一起使用,若忘记加上一个寻址模式,流中所有文本行都会被删除,比如要删除data文件中第二行:
$ sed '2d' data
需要说明的是,sed编辑器不会修改原文件,删除行只是从sed编辑器的输出中消失了,原始文件仍然包含“被删除的行“。
4.插入和附加文本
插入命令i会在指定行前增加一个新行,追加命令a会在制定行后增加一个新行。举两个例子:
# echo "line 2" | sed 'iline 1' line 1 line 2 # # echo "line 2" | sed 'aline 1' line 2 line 1
5.修改行
修改命令c逊于修改数据流中正行文本的内容,跟插入和附加命令一样,必须在sed命令中单独指定新行:
$ sed '2cThis is a black cat' data
6.转换命令
转换命令y是唯一可以处理单个字符的sed编辑器命令。准换命令会进行s1和s2的一对一映射,s1中地一个字符会转换成s2中第一个字符,第二个字符会转换成s2中第二个字符,直到处理玩指定字符。如果s1和s2长度不同,则报错。举个简单例子:
# echo "The number is 12345" | sed 'y/123/789/' The number is 78945
7.回顾打印
p命令用来打印文本行,=命令用来打印行号,l命令用来列出行。
# echo "This is a test" | sed 'p' This is a test This is a test # echo "This is a test" | sed '=' 1 This is a test
命令l可以打印出数据流中的文本和不可打印的ASCII字符,比如制表符的显示是 。
8.向文件写入读取数据
w命令向文件中写入行:$ sed [指定行]w 文件名
r命令将文件中的数据插入到数据流中:$ sed [指定行]w 文件名
二.gawk程序
gawk程序让流编辑迈上一个新台阶,它提供了一种编程语言而不只是编辑器命令。在gawk中可以定义变量来保存数据;使用算术和字符串操作符来处理数据;使用结构化编程语言,比如if-then来为数据增加逻辑;提取数据文件中的数据元素并将它们按另一顺序或结构重新放置,从而生成格式化报告。
使用gawk命令的格式:$ gawk optioons script file
gawk程序脚本用一队花括号来定义,由于gawk命令行假定脚本是单个文本字符串,所以必须将脚本放到单引号中。
1.使用数据字段变量
$0代表整个文本行,$n代表问本行中的第n个数据字段。
$ cat data line 1 line 2 line 3 line 4 $ $ gawk '{print $1}' data line line line line $
2.使用多个命令
只要在每条命令间加个分号即可。
# echo "This is a dog" | gawk '{$4="cat"; print $0}' This is a cat
3.在处理数据前运行脚本
BEGIN关键字强制gawk在读取数据前执行它后面制定的程序脚本。
# gawk 'BEGIN{print "Hello world!"}' Hello world!
4.在处理数据后运行脚本
跟BEGIN关键字类似,END关键字强制gawk在读完数据后执行脚本。
# cat script BEGIN{ print "The latest list of users and shells" print "Userid Shell" print "------ -----" FS=":" } { print $1 " " $7 } END{ print "This concludes the listing" }
# gawk -f script /etc/passwd The latest list of users and shells Userid Shell ------ ----- root /bin/bash daemon /bin/sh bin /bin/sh sys /bin/sh ... saned /bin/false **** /bin/bash This concludes the listing
三.学习资料
1.Common threads: Awk by example, Part 1
2.gawk 手册