sed处理文本的方法

sed在处理文本时,会先读取第一个输入行,将编辑命令应用于输入行,然后读取下一个输入行,并应用编辑命令。sed总是处理最新版本的行,因此sed中有多个编辑命令时,编辑命令的顺序对结果会有影响,下一个编辑命令会发生了变化的行而不是原始行,如示例:

[root@fanyue sed]# cat test
1 This is a pig.
2 This is a cow.
[root@fanyue sed]# sed 's/pig/cow/; s/cow/horse/' test
1 This is a horse.
2 This is a horse.

可以看到sed中第二个编辑命令处理的行是被第一个命令处理之后的内容。

模式空间

sed维护一种模式空间,即一个工作区或者临时缓冲区,当使用编辑命令时将在模式空间中存储单个输入行。一次一行的设计的有点是在读取非常庞大的文件时不会出现内存溢出或缓慢的问题。

初始时,模式空间包含有单个输入行的备份。然后按照命令顺序对模式空间的中的行进行处理。当应用了所有的指令后,当前行被输出,下一行被读入模式空间。然后脚本中的指令再次按顺序应用于新的行。即sed的处理步骤为:

  1. 生成输入行的备份到模式空间中
  2. 修改模式空间的中的备份
  3. 将修改后的备份输出到标准输出

回到上面的示例,如果我想将pig改为cow, cow改为horse改如何处理?

[root@fanyue sed]# sed 's/cow/horse/; s/pig/cow/' test
1 This is a cow.
2 This is a horse.

将命令的顺序反转即可!

sed还维护了一个称为保持空间(hold space)的另一个临时缓冲区,保持空间可以将模式空间的内容复制到保持空间并在以后检索它们。

sed的寻址

默认情况下,sed将命令用于每一个行。sed命令可以指定0个,1个或2个地址。每个地址都是一个描述模式、行号或者行寻址符号的正则表达式。

  • 如果没有指定地址,那么命令将应用于每一行。
  • 如果只有一个地址,那么命令应用于与这个地址匹配的任意行。
  • 如果指定了由逗号分隔的两个地址,那么命令将应用于匹配第一个地址的第一行和它后面的行,直到匹配第二个地址的行(包括此行)。
  • 如果地址后面跟有感叹号(!),那么命令就应该用于不匹配该地址的所有行。

例如,d命令代表删除匹配的行,一个d命令会删除所有的行,不会有任何输出,如:

[root@fanyue sed]# cat test
1 This is a pig.
2 This is a cow.
3 This is a dog.
4 And this is a monkey!!!
[root@fanyue sed]# sed 'd' test

当行号所有地址提供时,则命令只会删除匹配的那一行。例如,下面的示例只会删除第一行:

[root@fanyue sed]# sed '1d' test
2 This is a cow.
3 This is a dog.
4 And this is a monkey!!!

行号指由sed维护的内部行数。该计数器不会因为多个输入文件而重置。因此,不管指定多少个输入文件,1只代表输入流的第一行,如果输入流是多个文件,那么1代表第一个输入文件的第一行。

同样输入流也只有一个最后的行。可以使用寻址符号$指定。下面的示例删除输入的最后一行:

[root@fanyue sed]# sed '$d' test
1 This is a pig.
2 This is a cow.
3 This is a dog.

$符号不要和正则表达式中的$混淆,在正则表达式作为地址提供时,这个命令只影响与这个模式匹配的行。正则表达式必须封闭在斜杠(/)中。下面的删除命令:

[root@fanyue sed]# sed '/!$/d' test
1 This is a pig.
2 This is a cow.
3 This is a dog.

只删除以!结尾的行。

如果提供两个地址,那么就指定了命令执行的范围。下面的示例展示了删除两个地址之间的所有行,两个地址以逗号隔开:

[root@fanyue sed]# sed '/cow/,/monkey/d' test
1 This is a pig.

它删除从一个模式匹配开始,到由第二种模式匹配的行(包括此行在内)为止的所有行。下面的命令删除了文件中从5行到最后一行的所有行:

[root@fanyue sed]# sed '5,$d' /etc/passwd
root:x:::root:/root:/bin/bash
bin:x:::bin:/bin:/sbin/nologin
daemon:x:::daemon:/sbin:/sbin/nologin
adm:x:::adm:/var/adm:/sbin/nologin

可以混合使用行地址和模式地址:

  1,/^$/d

sed没有办法先行判断第二个地址是否存在匹配的行,因此当命令执行后sed会从一个匹配的行开始应用命令,如果没有出现第二个匹配的行,那么将删除所有的行。

跟在地址后面的感叹号会反转匹配的意义:

[root@fanyue sed]# sed '1,2!d' test
1 This is a pig.
2 This is a cow.

sed使用大括号({})将一个地址嵌套在另一个地址中,或者在相同的地址上应用多个命令。如果想指定行的范围,然后在这个范围内指定另一个地址,则可以嵌套地址。例如:

[root@fanyue sed]# cat test
This is a pig.
-------------
This is a cow.
-------------

this is a cat.
-------------
This is a dog.
-------------
And this is a monkey!!!
[root@fanyue sed]# sed '/cow/,/dog/ {/^$/d; s/-/*/g}' test
This is a pig.
-------------
This is a cow.
*************
this is a cat.
*************
This is a dog.
-------------
And this is a monkey!!!

sed & awk之sed的更多相关文章

  1. linux grep,sed,awk和diff的使用

    1:grep//显示行 # grep 'main' /home/myhome/a.c//将a.c含有main的行显示出来 # grep -v 'main' /home/myhome/a.c //显示除 ...

  2. awk与sed简明教程

    看到大牛写的关于awk和sed的简明教程,写得很好,为了尊重作者,就不全文转载了,这里标记下链接,方便以后查阅. awk简明教程:http://coolshell.cn/articles/9070.h ...

  3. Sed&awk笔记之awk篇

    http://blog.csdn.net/a81895898/article/details/8482333 Awk是什么 Awk.sed与grep,俗称Linux下的三剑客,它们之间有很多相似点,但 ...

  4. Sed&awk笔记之sed篇

    http://blog.csdn.net/a81895898/article/details/8482387 Sed是什么 <sed and awk>一书中(1.2 A Stream Ed ...

  5. SED&AWK

    SED   1.sed是流编辑器(stream editor)缩写,作用主要是文本替换 命令格式:sed ‘s/pattern/replace_string/' file或者cat file | se ...

  6. 正则表达式、find、grep、awk、sed

    1.正则表达式    (1)正则表达式一般用来描述文本模式的特殊用法,由普通字符(例如字符a-z)以及特殊字符(称为元字符,如/.*.?等)组成.   (2)基本元字符集及其含义       ^ :只 ...

  7. linux sed awk seq 正则使用 截取字符 之技巧

    [root@room9pc01 ~]# seq 5 1 2 3 4 5 [root@room9pc01 ~]# seq 2 5 2 3 4 5 seq 1 2 10 1 3 5 7 9 [root@d ...

  8. 1.Sed | Awk | Grep | Find

    1.Sed | Awk | Grep | Find 可以参考的文档链接 CentOS7 查看 当前机器 已经启动的端口的Shell命令: netstat -lntup | awk -F' ' {'pr ...

  9. 通过awk 和 sed 将多余的列剔除

    通过awk 和 sed 将多余的列剔除 名词注释: awk -F 指定分隔符 OFS 指定输出分隔符 sed sed "s/|/test/2" a.log 将第二个 | 线替换为 ...

随机推荐

  1. 02-里氏替换原则(LSP)

    1. 背景 有一个功能p1,由类A完成,现在需要将功能p1进行扩展,扩展后的功能为p3,p3由原功能p1和新功能p2组成,而新功能p3和p2均由类A的子类B来完成,子类B在完成新功能p2的同时,可能会 ...

  2. phpexcel 导出到xls文件的时候出现乱码解决

    在header() 前面加上ob_end_clean() 函数, 清除缓冲区, 这样就不会乱码了! <?php include 'global.php'; $ids = $_GET['ids'] ...

  3. Emacs org-mode导出html出错

    不知道为什么,当org文件中含有#+TITLE:xxx时,导出会报类似下面的错误: Wrong type argument: listp, #("xxx" 0 3 (:parent ...

  4. jsp中的JSTL与EL表达式用法

    JSTL (JSP Standard Tag Library ,JSP标准标签库) JSTL标签库分为5类:JSTL核心标签库.JSTL函数标签库.数据库标签库.I18N格式化标签库.XML标签库. ...

  5. string字符串js操作

    String 对象方法 方法 描述 anchor() 创建 HTML 锚. big() 用大号字体显示字符串. blink() 显示闪动字符串. bold() 使用粗体显示字符串. charAt() ...

  6. luogu P4082 [USACO17DEC]Push a Box

    传送门 一个人推箱子,和之前的华容道中的棋子移动有异曲同工之妙,因为每次可以让人走到箱子的其他方向上,或者推一下箱子 所以状态可以设成\(f_{i,j,k}\),即箱子在\((i,j)\),人在\(k ...

  7. js 获取当前日期或者前、后N天yyyy-MM-dd的方法

    //js获取当前日期.当前日期前.后N天的标准年月日 //day=0为当前天,day=7为前7天,day=-7为当前日期的后7天 function getstartdate(day) {        ...

  8. mysql 原理~ index的详解

    一 简介:今天咱们来介绍下index的一些东西 二 数据的基本存储结构 1 磁盘空间被划分为许多大小相同的块(Block) 在内存中读出是页(Page).   2 一个表的这些数据块以链表的方式串联在 ...

  9. c# 创建项目时提示:未能正确加载“microsoft.data.entity.design.bootstrappackage

    vs 2005 ,vs 2008, vs 2010,安装后有时出现这个错误(我的机器装的x64的win7),很烦人.找了很多地方都不能解决.其实说起来还是开发国家牛,轻易就解决了这个问题.其实出现这个 ...

  10. python f-string

    文章目录 1. 主要内容 1.1. 旧时代的格式化字符串 1.1.1. Option #1: %-formatting 1.1.2. 怎样使用 %-formatting 1.1.3. 为什么 %-fo ...