原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处。

sed命令有两个空间,一个叫pattern space,一个叫hold space。这两个空间能够证明人类的脑瓜容量是非常小的,需要经过大量的训练和烧脑的理解,才能适应一些非常简单的操作。

不信看下面简单的命令,作用是,删除文件中最后两行。

sed 'N; $!P;$!D;$d' file

《Linux生产环境上,最常用的一套“Sed“技巧》

一文中,我们介绍了常用的sed命令和操作,而且使用了两张图来作为辅助。但可惜的是,这两张图,严格来说是不准确的 (比如s命令,只是其中的一个子集),即使它能够帮助初学者快速入门。

本篇属于sed的中级用法,常见在一些sed脚本中,在日常中应用并不多,但往往能够获得意想不到的效果。

原理

工作模式

这要从sed的工作模式来说起。

按照我们读取一个文件的尿性,一般是持续循环读取。比如下面的python代码,print代表p命令。

with open('file', 'r') as f: for line in f.readlines(): print(line)

sed命令在这之上,还缓冲了另外一个东西。那就是“上一行的内容” ,叫做hold space。而当前行,叫做patter space。用python简单表现一下:

hold_space = ""with open('file', 'r') as f: for pattern_space in f.readlines(): print(hold_space,pattern_space) hold_space = pattern_space

具体过程,大体与上面的代码类似,以上面的图为例。在这个例子中,hold space不参与运算,是全程无感的:

1、 读取当前行 wtf.. 到 Pattern space

2、 执行命令p,这会打印出当前行

3、 把Pattern space的内容,赋值给Hold space

4、 继续下一行的处理,循环这个过程

一个例子:x

但我想稍微操作一下这两个缓冲区。这个操作就是swap,使用x表示,这也是一些文本编辑器的一贯尿性。

也就是,在p之前,我们加上了个x。表示先将这两个缓冲区进行置换,然后再往下走。

hold_space = ""with open('file', 'r') as f: for pattern_space in f.readlines(): swap(hold_space,pattern_space) print(hold_space,pattern_space) hold_space = pattern_space

让我我们来想象一下这个过程。

1、 刚开始,hold_space的内容是空。然鹅,还没被填充,它就被使用了,和当前行进行了置换

2、 p命令用在了置换后的缓冲区上,第一次打印出了空行,fuck

3、 继续嘟嘟嘟,现在到了最后一行,马上进行了置换,没机会打印就到了hold_space中了

4、 当前行,存放的是倒数第二行的数据,最后一行见光死,就永远没有机会面世了

我们当然有办法把它搞出来,比如,我执行偶数次的交换x。

sed -n 'x;x;x;x;p' file

有木有一股骑着羊驼走天下的的感觉?

应用

举个栗子

你可能会想,我对这两个缓冲区交换,有什么用?接下来看这个文件。

小姐姐味道公众号CEO加菲猫经理IT Manager系统毁灭师Sysadmin小哥哥味道Developer爱卖东西的经理Sales Manager风清扬Dog

文件奇数行是名称,偶数行是职位。我们想要输出所有Manager的名字。就可以使用下面的命令。

sed -n -e 'x;n' -e '/Manager/{x;p}' file

命令分为两个部分。

x;n 表示将偶数行保存在pattern space,那么奇数行就保存在hold space中。

/Manager/{x;p} 命令将在pattern space上执行对Manager关键字的查找。如果符合条件,则再次交换p和h缓冲区,输出奇数行对应的名字。

上面的x和n,就是针对这两个缓冲区的命令。这样的命令有很多。

命令

这些命令,如果多了,可以使用{}包围起来,就像上面的命令一样。这些命令的位置与我们上一篇所说的,在同一个地方。

常用的:

x 请容许我用英文装个b:Exchange the contents of the hold and pattern spaces.

d 清空当前的pattern space,然后进入下一个循环

D 删除pattern space的第一行(multiline pattern)

h 复制pattern space到hold space

H 追加pattern spaced到hold space

g 复制hold space到pattern space

G 追加hold space到pattern space

n 读取下一个输入行到pattern space

N 追加下一个输入行到pattern space,同时将两行看做一行,但是两行之间依然含有换行符

p 打印当前的pattern space

P 打印当前的pattern space中的第一行

不常用的

上次提到的推箱子游戏,就用了很多这种东西。为了使使用者在书写sed脚本的时候真正的”自由”,sed还允许在脚本中用”:”设置记号。标签,有种类似编程语言的特性了。

q 退出sed,可以增加执行速度

l 列出当前行,包含不可打印字符

l width 列出当前行,使用一个width characters结尾

b label 跳到相应的标签,分之命令。

t label if分支,从最后一行开始,条件一旦满足或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾。测试命令。

T label 错误分支,从最后一行开始,一旦发生错误或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾。

当然还有其他更不常用的,可以使用man命令查看

man sed

一些命令:开启训练模式

看着一行行进行处理,好像很简单是不是?不可能的,看下面几个简单的命令,训练一下生锈的脑子。

一个流水线一样的命令

sed -n '2{h;n;x;H;x};p' file

交换第2行和第3行的内容

输出最后一行

sed 'N;D' file

输出文件中最后两行

sed '$!N; $!D' file

删除文件中最后两行

sed 'N; $!P;$!D;$d' file

打印偶数行的另一种写法

sed –n 'n;p' file

每隔5行加入一个空行。

sed 'n;n;n;n;G' file

输出含AAA和BBB和CCC(任意顺序)的段落

sed -e '/./{H; $!d;}' -e 'x;/AAA/!d; /BBB/!d; /CCC/!d' file

颠倒行序(使末行变首行,首行变末行)

sed -n '1!G; h; $p' file

这个命令有点绕,首先,1!G对除了第一行的其他行进行了G操作,然后反向复制回去,到了最后一行,就直接打印Pattern Space。$表示到了最后一行执行下面的命令,也可以是${p}

一个带标签的用法

sed -e :a -e '$q;N;11,$D;ba'

打印最后10行。a是标签。语法就是单独的行,使用:分隔。

End

为了提高你在公司的竞争力,你是可以弄一堆sed脚本唬人(埋雷)的。和某些perl脚本一样,即使是有相关经验的开发着,理解起来也要下点功夫,就不要说其他人了。

这就是sed,简约但不简单的命令,本文算是一个中级入门。中级入门也有点烧脑,因为你的脑瓜里,需要一直维护着这两个缓冲区。又是置换,又是清空,相当于人肉状态机。当然,怎么把这个过程讲的尽量简单一点,还是浪费了作者不少脑细胞的。哪怕你点个赞,也是延缓小姐姐走向老年痴呆时间的一个途径。有了你的支持,小姐姐也可以想点技术之外的事情,比如喷喷bat什么的。

作者简介:小姐姐味道(xjjdog),一个不允许程序员走弯路的公众号。聚焦基础架构和Linux。十年架构,日百亿流量,与你探讨高并发世界,给你不一样的味道。我的个人微信xjjdog0,欢迎添加好友,​进一步交流。​

linux sed给空文件首行插入_Sed命令高级功能,学好了工作不愁相关推荐

  1. linux sed给空文件首行插入_Linux系统中sed命令在文件某行前后添加内容的用法

    linux的sed工具是十分强大的,能很容易的实现在某关键词的前一行或后一行增加内容.今天在批量修改tomcat的日志时就用到了该功能. 一.在某行的前一行或后一行添加内容 具休操作如下: 复制代码 ...

  2. linux sed给空文件首行插入_linux下批量修改文件后缀名以及合并多行

    写在前面 感谢乔兄送测的公司,让我终于所有营业 part1讲下怎么解决小问题 part2分享谈判过程 part3mark张兄的奶茶 PART1 linux下批量修改文件后缀名以及合并多行 近期师兄在做 ...

  3. linux创建空文件方式,在Linux下创建空文件的方法

    我曾经以此为面试题,以测试技术人员对操作系统及指令的理解程度. 建立空文件,看上去没有意义,而在实际工作中仍然有实际的作用.比如作为驱动事件或标志文件,其实作为文件实体,文件本身已经在操作体统中体现了 ...

  4. 如何使用sed在文件中确定行插入带有变量的字符串

    背景 最近在研究一键部署,其中有一个环节,是要使用shell脚本放开防火墙的某个端口号 方法 使用shell中常见的插入文本命令:sed 问题 如果已经预知要打开的端口号如6379,可以使用:sed ...

  5. linux中向空文件写入内容,linux – 为什么写入现有文件比写一个新的空文件更快?...

    我使用MappedByteBuffer在linux中编写文件. File file = new File("testFile"); RandomAccessFile raf = n ...

  6. linux 只删除空文件夹,Linux如何删除空文件夹-linux删除文件夹

    请关注本头条号,每天坚持更新原创干货技术文章. 如需学习视频,请在微信搜索公众号"智传网优"直接开始自助视频学习. 1. rmdir命令简介 本文主要介绍rmdir命令,该命令用于 ...

  7. Linux下置空文件的方法小结

    1.彻底置空,也就是ls文件的大小为0,文件里面什么都没有 (1): > filename      (2)true > filename      (3)cat /dev/null &g ...

  8. 如何在linux编写perl脚本,关于linux:如何在perl脚本中插入awk命令?

    我想在脚本中添加此awk命令,但始终出现错误. 我已放入"",但仍然出现错误. system("awk -F"\t" '{ for ( i=1; i& ...

  9. Linux下在文件内部指定行(首行、末尾行等)插入内容

    1.在文件的首行插入指定内容: :~$ sed -i "1i#! /bin/sh -" a 执行后,在a文件的第一行插入#! /bin/sh - 2.在文件的指定行(n)插入指定内 ...

最新文章

  1. 秒过,度目智慧通行让常态化防疫更高效
  2. Struts2的2.5.10版本找不到StrutsPrepareAndExecuteFilter过滤器 与 struts.xml文件通配符异常问题
  3. P1311 选择客栈
  4. 修改TFS与本地源代码映射路径
  5. python文件输出log_Python同时向控制台和文件输出日志logging的方法
  6. 五、Python第五课——Python中组织列表的相关函数
  7. 主流数据库连接池性能比较 hikari druid c3p0 dbcp jdbc
  8. DC-DC转换器的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  9. 统计|(可/无)重复双因素方差分析一般步骤及分析表
  10. html5 人脸活体识别,基于HTML5的人脸识别活体认证的实现方法.pdf
  11. setcpu_SetCPU中文版
  12. 淘宝电商数据分析-Python
  13. 2022年推土机司机(建筑特殊工种)考试题库及推土机司机(建筑特殊工种)考试技巧
  14. 并发之volatile底层原理
  15. 敏捷的三个中心;再谈Buffer
  16. Oracle EBS 名词解释
  17. 修改数据库编码格式UTF-8
  18. hdu 6656 Final Exam
  19. Java 利用“云之讯”实现发送短信接口
  20. 覆盖5大主流开发平台的报表控件,它值得你一看

热门文章

  1. android中可口的吐司,一种信息提示机制——Toast
  2. 102 二叉树层序遍历
  3. linux useradd命令使用示例
  4. python3 读取配置文件中的参数值替换yaml文件中的占位符(变量)
  5. K8S完整部署项目实战案例
  6. python Django数据库保存操作
  7. kibana操作elasticsearch:新增数据(自定义id)
  8. Linux netstat查看网络连接信息
  9. zookeeper实现分布式锁的原理及具体使用案例
  10. MySQL设置数据库的字符编码为utf8