刚学习了一下Sed和AWK,乘热打铁就Sed和AWK的简单使用做个笔记。手头还有一本四百多页的机械工业出版社的《sed与AWK》。回头看完这本书后再补充一些不太难又实用的内容以后贴到wiki里。
书本学来的东西有时候就是太偏理论,欢迎大家提供一些比较实用的例子。也欢迎就不对的地方批评建议。
PS:计划做一个系列的笔记,主要就是系统管理和一些实用的命令。想先发在论坛大家批评修改后再贴到wiki,大家有什么想法?
下面正文。
1 定义
Sed : 处理纯文本流的文本编辑器。
AWK : 一种输出格式化语言。
啥?不懂?不懂没关系,实践几次以后就会有点体会了。越多的使用它就会对它理解的更深。现在不妨先跳过它。回头再来看这个定义。
2 Sed
Sed可以用来处理文件,我们来举个实际的例子。
首先我们来创建两个文件,随便用什么工具,Kate啊,vim啊,gvim啊都可以,如果你在学习vim正好这也是个应用的机会。
下面我用touch,echo和重tee来创建两个文件,这样做没什么方便的,纯粹就是为了熟悉命令。
首先创建三个个空文件。
touch one.txt two.txt three.txt
给两个空文件分别加入内容
echo -e "a\nb\nc\nd\n" | tee ./one.txt
echo是终端打印的命令,-e选项是说在字符中会使用到转义符号,就是这里的\n了,学过c的同学知道它和c是一样的。甚至你可以这样
printf "d\ne\nf\ng\n" | tee ./two.txt
这就和c更像了。上面的命令可以把内容加入two这个文件中。其中|是通道,将echo和printf的输出传递给tee,而tee的作用是,不仅在终端打印数据还会把数据输送到文件。如果希望添加而不是不是覆盖可以加上选项 -a
echo -e "a\nb\nc\nd\n" | tee -a ./two.txt
然后我们使用下面命令
sed -e s/a/z/g one.txt two.txt > three.txt
你可以用cat来查看内容
cat ./three.txt
输出如下
z
b
c
d
d
e
f
g
我们可以这样理解sed,它把指定的一些文件或输入用一组命令来处理,然后输出到标准输出中。
在这里,指定的文件就是one.txt 和two.txt,而处理的命令就是 s/a/z/g,标准输出就是终端输出,在这里我们通过重定向将它定向到了一个文件里。
我们来看看这个命令,熟悉vim的同学会发现它和vim是一样的,就是搜索和替换,就是把a替换成z,/g的意思是整行的替换,去掉这个只会替换在一行里找到的第一个。当然,在这个例子里是没有影响的。
其实sed的命令可以有多个,比如
sed -e 's/a/z/g; s/b/y/g' one.txt two.txt > three.txt
再用cat看看输出,发现了么,这里的用’‘把命令扩起来,用分号分割不同的命令,其实,只有一个命令的时候也建议你用’’,这样可以更清楚。
sed还可以多行记录
sed '
>s/a/z/
>s/b/y/ ' one.txt two.txt
其实sed最方便的还是可以把命令写进文件里,这样就可以重复利用,不用每次都敲那么多代码了。
创建一个文件,这次我们用vim好了
vim edits.sedscr
s/a/z/
s/b/y/
然后
sed -f edits.sedscr one.txt two.txt > three.txt
3 AWK
AWK的用法和sed其实非常的相似。同样的,他是输入一个命令或一组命令或是写着命令的文件,以及数据或写着数据的文件。然后格式化后输出。
我们来举个实际点的例子。比如我们要提取/etc/passwd里的信息,我们知道这个文件里储存的是用户的资料,电脑通过字段可以很轻松的识别,
可是对于系统的管理者来说就没那么方便了,本身记忆那么多字段也是一种负担,现在我们就通过awk来处理这些信息使其变得清晰。
注意此命令要在root后实用,不是所有人都有权限查看/etc/passwd文件的。
#awk -F":" '{print "usrename:" $1 "\t\t\t user ID:" $3}' /etc/passwd
下面是我的部分输出。
usrename:at user ID:25
usrename:avahi user ID:487
usrename:bin user ID:1
usrename:daemon user ID:2
usrename:dhcpd user ID:491
usrename:dnsmasq user ID:488
usrename:fetchmail user ID:481
usrename:ftp user ID:40
usrename:ftpsecure user ID:482
usrename:games user ID:12
usrename:gdm user ID:480
同样的被’'扩起来的是命令,其中我们知道在passwd文件中第一个字段是用户名,第三个字段是用户ID,默认awk是以空格作为划分字段的依据的。
使用了 -F":"后就改成了以:作为划分的依据了。
同样的AWK的命令可以写进文件
vim print.awk
BEGIN{
FS=":"
}
{printf "\nusername:" $1 "\t\t\t user ID:" $3}
END{
printf "\ndone\n"
}
然后运行
awk -f print.awd /etc/passwd
你可以看到和上面差不多的输出,其中BEGIN和END的内容只会被执行一次,在这个例子中END的用途只是打印了一个done,告诉你已经执行完成了。
你完全可以去掉它。
从这个例子你可以窥见,AWK可以编写很复杂的命令来处理复杂的数据,这也许就是为什么我们会说编写AWK程序了。有时它确实就像是一个程序。
我们可以很容易想到的AWK可以处理的东西就是系统日志了。无论是对于管理系统,排除系统故障,系统日志都是非常重要且有用的。当然,系统日志的处理没有处理passwd那么简单。这部分内容等我实践过以后再补充。:P(也欢迎大家补充啊~~~)