[ 分享 讨论 ]Sed 和 AWK 的一些简单使用

刚学习了一下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(也欢迎大家补充啊~~~)

sed 是编辑器么?我记得说是按行处理的终端文本处理工具还差不多。暂时只会用 sed 替代一些内容,不会正则表达式写不了太复杂的

在我看到的资料里说 sed 和 AWK 都是起源于古老的 ed 编辑器,话说你可以在终端输入 ed 玩一下。当然说是按行处理的终端文本处理工具好像也不错,貌似还利于理解一点。表示这个定义是抄书的,还是不改了吧。

awk 貌似在处理各种数据报表的时候比较好用
反正 C 语言在 awk 下貌似是可以用的?
正则表达式苦手表示这两个还真不怎么会用

正则表达式是一门艺术,表示正在学习。当然有学习就会有笔记,这个也在我的计划之中。倒时候指教啊~可以共同学习。

这个世界上学一门艺术都不是简单的活啊.linux 也是一门艺术了… 自己站在门槛边上徘徊还没有坚定踏进去
学 sed awk 其实可以也是在学正则表达式了吧. 虽然是应该是比较基础的. 正则表达式才是这两个应用的本体啊
awk 的倒是可以用上一些 C 语言