“ 在使用了grep实现了对文本的查找以后,我们又有了新的需求,现在我不只是想查找了,我想实现对文本的替换操作了,这个时候就到了我们的sed出场的时候了。”
首先展示上一篇文章末尾作业的答案,
# 查找所有包含J的行 不区分大小写 输出行号
grep -n -i 'j' test1
# 查找包含7的行 输出有多少行
grep -c '7' test1
# 使用两种方法查找f出现的行数
grep -c 'f' test1
grep 'f' test1 | wc -l
# 找到包含f和6数字的行 然后删去数字行并存为文件test2
grep 'f' test | grep '6' | cut -d '#' -f 1,2 > test2
# 提示使用 | 和 cut命令
(大家请认真阅读最后一条命令,如果你看不懂请回顾Linux系列教程8-10以及Linux进阶教程)
上节课讲解了关于grep的操作,相信大家通过上面的练习应该已经知道grep的强大之处了吧。但是,我们还有更为强大的武器,它们就是sed和awk。
如果我们想要更好的使用这两个武器来进行文本处理的话,我们还需要学习一下这两个武器的组装(参数和关键词)和弹药(正则表达式)。这样我们才能更加完美的使用这两把武器,接下来我们先给大家的sed开个简要的头,然后我们就要开始正则表达式的学习了。
sed简介
sed 是 stream editor 的缩写,中文称之为“流编辑器”,相信大家看sed系列教程的时候,已经是看过我的Linux系列的2-12左右的水平了(或者你本身对Linux有了自己的基本理解)。
那么你一定知道所谓的流编辑器是什么意思,它接受来自管道的输入,然后进行处理,进而标准输出。这一类的处理命令还包括了sort grep cut tr等等。
大家可能多多少少都听过sed的大名,但是没有真正的接触过它,那么它到底有什么作用呢?sed是基于行对输入文本进行处理的,也就是它会按顺序对每一行进行处理,然后将结果写到标准输出里,而不会修改输入文件。
而sed的工作过程,大家目前可以理解为,sed读取一行文本,放进一个地方,然后按照你的要求(命令)进行处理,处理结束以后,打印处理结果到标准输出。
p命令和-n参数
我给大家带来的sed学习的第一个步骤,不是替换,也不是删除增加行,更不是查找,而是通过两个非常平淡,但是能让你深入了解sed工作模式的两个东西,p命令和-n参数。
我使用vim创建了这样的一个文件
下面我使用sed来模拟一下cat的效果
sed '' test
它可以输出和cat一样的结果。这条命令的含义是,输入文件test给sed,让sed对每一行进行处理,但是****' '内是放我们处理命令的地方****,我们这里****什么都没有,所以sed会直接把每一行都拿出来什么也不做,然后再输出出去****。
下面讲解p命令,
p命令:打印,亦即将某个选择的数据印出,大家目前把它理解为打印工作区的内容即可。
sed 'p' test
你会发现,我们的每一行居然打印了两次,这是为什么呢?
因为我们这次是有命令执行了,我们的****行被读进了工作区,然后执行p命令进行打印****,****然后sed再自已把行被处理(此处没有处理命令,所以打印的还是原样)的结果打印出来****。这样就造成了打印出来两行的情况。
那么我们不想出现这种情况,我们就想执行命令,不让sed手贱给我们把结果打印出来,我们该怎么做呢?
-n参数:仅显示script处理后的结果。
sed -n 'p' test
如果我们输入空命令则会
大家看懂了吗,上面的我们不让sed输出处理后的结果,所以只有p打印出来的结果。而下面压根没有处理命令,我们又-n不让sed进行输出,也就是说,sed什么也不输出。
这就是-n参数的作用,网上很多地方都讲了,使用p命令的时候一定要配合-n参数,但是都没有告诉你为什么要这么做,相信看了上面的讲解,你应该已经懂得了-n参数为什么能起到这样的效果了。
上面的讲解大家要反复的看,反复的思考,直到你真的懂了,至少你得差不多懂了,不然后面的很多地方都没办法很好的领会。
数字地址范围
在sed中,我们有个经典的概念,称为地址范围。这里的地址和我们平时进行编程的时候使用的指针指向的地址是不一样的。那个是真正的地址,我们这里就是指定一下我们sed打算处理的数据的行范围。
比如,我们只想处理前十行,或者处理第15到30行,再或者,它可以处理10到包含某些特定字符的行等等。本文对处理具有正则含义的行不做讲解,后面讲完了正则表达式会再次进行讲述。
下面展示一下数字地址范围的效果,数据依旧使用我们的示例数据
sed -n 5p test
sed -n 1,5p test
sed -n 2,3p test
大家应该已经看到了输出的结果了,使用了-n参数让sed少比比,我们就更加专注于命令的执行。这里命令的前面,我加上了一个数字,这个数字代表了我们要处理的行,也就是说,这个地方限定了我们要处理的范围。
它可以打印特定的行,也可以在一个范围内进行处理,比如我的第二和第三条命令,我就是指定了需要处理的地址,是第一行到第五行以及第二行到第三行。
$代表的地址
我们上面进行选址的时候,大家有没有这样的一个疑问,就是我们使用数字选址,可以从1开始取任意行。如果我们想取第八行到最后一行,我们好像就无能为力了。这个时候再使用wc -l还有点多此一举。
所以sed给我们提供了一个$符号代表最后一行的地址。注意这个符号是地址,不是我们正则表达式中的匹配结尾。我最开始使用的时候总会把它当成正则的结尾,然后报错回来找不到错误。
打印test文件中的第三行到最后一行,
sed -n '3,$p' test
这就是$符号定地址的使用了。
到这里为止,你已经对sed有了一个初步的了解了,最起码可以使用sed输出数据了,从下一篇文章开始,将要讲解关于正则表达式的知识。通过正则表达式的使用,让你透彻的了解到文本处理的精华。
如果你喜欢我的文章,请收藏我的文章并且给我个赞,你的支持就是我更新的最大的动力,关注我会有更多惊喜哦,专注于生物信息学以及数据分析入门和进阶教程,也许我给不了你从10-100,但是我可以给你最好的从0-10!
最后,关注我的公众号,领取更多学习资料吧!!!
打开v搜索,”轻松玩转生信“或者从下面文章进去获取二维码关注哦