一、流编辑器 sed 与命令 sed

  Linux 中,常使用流编辑器 sed 进行文本替换工作。与常使用的交互式编辑器(如vim)不同,sed 编辑器以批处理的方式来编辑文件,这比交互式编辑器快得多,可以快速完成对数据的编辑修改。

  一般来说,sed 编辑器会执行以下操作:

1)一次从输入中读取一行数据;

2)根据所提供的编辑器命令匹配数据;

3)按照命令修改流中的数据;

4)将新的数据输出到 STDOUT。

  在 sed 编辑器匹配完一行数据后,它会读取下一行数据并重复这个过程,直到处理完所有数据。使用 sed 命令打开一个 sed 编辑器。sed 命令的格式如下:

sed [options] edit_commands [file]    # [ ] 中的内容为可选可不选

  其中,options 为命令选项,选择不同的 options 可以修改 sed 命令的行为,主要有 3 个选项:

1)-e 选项: 在处理输入时,将 script 中指定的编辑命令添加到已有的命令中。通俗的说,就是在 sed 后面直接添加编辑命令:

sed -e 'edit_commands' [files]

  sed 命令在默认情况下使用的是 -e 选项。当只有一个编辑命令时,-e 选项可以省略;但是当要在一条 sed 语句中执行多个编辑命令时,就需要使用 -e 选项了:

sed -e 's/root/ROOT/g; s/bin/BIN/g' /etc/passwd       # 使用 sed 同时执行两条编辑命令(本文大部分用例都直接使用 /etc/passwd 文件)

sed -e 's/root/ROOT/g' -e 's/bin/BIN/g' /etc/passwd   # 使用 sed 同时执行两条编辑命令

2)-f 选项:在处理输入时,将 file 中指定的编辑命令添加到已有的命令中:

  前面提到,在需要同时执行多条编辑命令时,可以使用 -e 选项。但是当所需要执行的编辑命令数量很多时,每次使用 sed 时一行一行地敲显然不是很方便,这时可以将所用到的 sed 编辑命令写入一个文件,然后使用 sed -f 选项来指定读取该文件:

$ cat script.sed
$ s/root/ROOT/
$ s/bin/BIN/
$ s/home/HOME/
sed -f script.sed /etc/passwd

3)-n 选项: 不产生命令输入:

sed -n 's/root/ROOT/' /etc/passwd

  使用 -n 选项不会将流编辑器的内容输出到 STDOUT,通常将 -n 选项与 p 命令结合起来使用,以只打印被匹配的行。

  除了这三个选项外,sed 编辑器还提供了许多命令,用来进行更详细的操作,简单列一下,后面再仔细介绍:

命令 描述
s 文本替换操作
d 删除操作
i 插入操作
a 附加操作
c 将一行文本修改为新的行
y 逐字符替换
p 打印文本行
= 打印行号
w 向文件中写入数据
r 从文件中读取数据

二、使用 sed 命令进行文本替换

  sed 使用 s 命令来进行文本替换操作,基本格式如下:

sed 's/srcStr/dstStr/' file

  其中,srcStr 为想要替换的文本,dstStr 为将要替换成的文本。使用 s 命令时,sed 编辑器会在一行一行地读取文件 file,并在每行查找文本 srcStr,如果找到了,则将该处的 srcStr 替换为 dstStr。

  / 字符为界定符,用于分隔字符串(sed 编辑器允许使用其他字符作为替换命令中的字符串分隔符):

sed 's!/bin/bash!/BIN/BASH!' /etc/passwd    # 使用 ! 作为字符串分隔符

  默认情况下,替换命令只会替换掉目标文本在每行中第一次出现的地方。若想要替换掉每行中所有匹配的地方,可以使用替换标记 g。替换标记放在编辑命令的末尾。除了 g 外,还有几种替换标记:

1)数字:指明替换掉第几次匹配到的文本,没有设置这个标记时,默认是替换第一次匹配的文本:

sed 's/root/ROOT/2' /etc/passwd

  这行命令将 /etc/passwd 文件中每行的第 2 个 root 替换为 ROOT;

2)g :替换所有匹配到的文本:

sed 's/root/ROOT/g' /etc/passwd

  这行命令将 /etc/passwd 文件中的 root,全部替换为 ROOT;

3)p :打印与替换命令中指定模式(srcStr)相匹配的行:

sed 's/root/ROOT/p' /etc/passwd

  执行这命令,会在 STDOUT 上看到包含有 root 的行被输出了两次,一次是 sed 编辑器自动输出的;另一次则是 p 标记打印出来的匹配行。

  单独地使用 p 标记没什么用处,通常将 p 标记和 -n 选项结合起来使用,这样就可以只输出被匹配替换过的行了:

sed -n 's/root/ROOT/gp' /etc/passwd    # 将 /etc/passwd 中所有的 root 都替换成 ROOT,并输出被修改的行

  注:可以使用 " = " 命令来打印行号,用法与 p 一样。  

4)w file :将替换的结果写到文件中,不过只保存被修改的行,与 -n + p 的功能类似:

sed -n 's/root/ROOT/g w change.txt' /etc/passwd     # 将 /etc/passwd 中所有的 root 都替换成 ROOT,并将被修改的行保存到文件 change.txt 中去

三、使用行寻址对特定行进行编辑

  默认情况下,sed 编辑器会对文件中的所有行进行编辑。当然,也可以只指定特定的某些行号,或者行范围来进行流编辑,这需要用到行寻址。所指定的行地址放在编辑命令之前:

[address] commands

3.1 使用数字方式进行行寻址

  sed 编辑器将文本流中的每一行都进行编号,第一行的编号为 1 ,后面的按顺序分配行号。通过指定特定的行号,可以选择编辑特定的行。举几个例子:

sed '3 s/bin/BIN/g' /etc/passwd    # 将第3行中所有的 bin 替换成 BIN
sed '2,5 s/bin/BIN/g' /etc/passwd   # 将第2到5行中所有的 bin 替换成 BIN sed '10,$ s/bin/BIN/g' /etc/passwd  # 将第10行到最后一行中所有的 bin 替换成 BIN

  注:行寻址不止对替换命令有效,对其他命令也都是有效的,后面也会用到。

3.2 使用文本模式过滤器过滤行

  sed 编辑器允许指定文本模式来过滤出命令要作用的行,格式如下:

/pattern/command

  必须使用斜杠符 " / " 将要指定的文本模式 pattern 包含起来。sed 编辑器会寻找匹配文本模式的行,然后对这些行执行编辑命令:

sed -n '/root/s/bin/BIN/p' /etc/passwd    # 寻找包含有字符串 root 的行,并将匹配行的 bin 替换为 BIN

  与数字寻址一样,也可以使用文本过滤区间来过滤行:

sed '/pattern1/,/pattern2/ edit_command' file

  这行命令会在文件 file 中先寻找匹配 pattern1 的行,然后从该行开始,执行编辑命令,直到找到匹配 pattern2  的行。但是需要注意的是,使用文本区间过滤文本时,只要匹配到了开始模式(pattern1),编辑命令就会开始执行,直到匹配到结束模式(pattern2),这会导致一种情况:一个文本中,先匹配到了一对 pattern1、pattern2,对该文本区间中的文本执行了编辑命令;然后,在 pattern2 之后又匹配到了 pattern1,这时就会再次开始执行编辑命令,因此,在使用文本区间过滤时要格外小心。举个例子:

sed -n '/root/,/nologin/ s/bin/BIN/p' /etc/passwd

  这行命令对 /etc/passwd 进行了两次文本区间匹配,结果如下:

  

四、使用 sed 命令删除行

  sed 编辑器使用 d 命令来删除文本流中的特定行。使用 d 命令时,一般需要带上位寻址,以删除指定的行,否则默认会删除所有文本行:

sed '/root/d' /etc/passwd   # 删除匹配 root 的行

sed '2,$d' /etc/passwd    # 删除第2到最后一行

五、使用 sed 命令插入和附加文本

  sed 编辑器使用 i 命令来向数据流中插入文本行,使用 a 命令来向数据流中附加文本行。其中:i 命令会在指定行前增加一个新行;a 命令会在指定行后增加一个新行。

  需要注意的是,这两个命令都不能在单个命令行上使用(即不是用来在一行中插入或附加一段文本的),只能指定插入还是附加到另一行。命令格式如下:

sed '[address][i | a]\newline' file

  newline 中的文本即为将要插入或附加在一行前面或后面的文本。常常使用这两个命令结合行寻址在特定的行前面或后面增加一个新行。举个例子:

sed 'i\Insert a line behind every line' /etc/passwd      # 向数据流的每一行前面增加一个新行,新行的内容为 \ 后面的内容

sed '1i\Insert a line behind the first line' /etc/passwd   # 在数据流的第一行前面增加一个新行

sed '3a\Append a line after the third line' /etc/passwd      # 在数据流的第三行后面增加一个新行
    
sed '$a\Append a line in the last line' /etc/passwd      # 在数据流的最后一行后面增加一个新行

六、使用 sed 命令修改行

  使用命令 c 可以将数据流中的整行文本修改为新的行,与插入、附加操作一样,这要求在 sed 命令中指定新的行,格式如下:

sed '[address][c]\newtext' file

  newtext 中的文本为匹配行将要被修改成的文本。

sed '3 c\New text' /etc/passwd     # 将数据流中第三行的内容修改为 \ 后面的内容

sed '/root/ c\New text' /etc/passwd  # 将匹配到 root 的行的内容修改为 \ 后面的内容

sed '2,4c\New text' /etc/passwd     # 将第2到4行的内容修改为 \ 后面的内容,但是不是逐行修改,而是会将这之间的  行用一行文本来替代

  注意这里对地址区间使用 c 命令进行修改时,不会逐行修改,而是会将整个区间用一行修改文本替代。

七、使用 sed 命令逐字符转换

  使用 y 参数可以按要求对文本进行逐字符转换。格式如下:

[address]y/inchars/outchars/

  转换命令会对 inchars 和 outchars 的值进行一对一的映射。inchars 中的第一个字符会被转换成 outchars 中的第一个字符;inchars 中的第二个字符会被转换成 outchars 中的第二个字符;... 直到处理完一行。如果 inchars 和 outchars 的长度不同,则 sed 编辑器会产生一个错误消息。举个例子:

echo abcdefggfedcba | sed 'y/acg/ACG/'

  输出结果为 AbCdefGGfedCbA。

八、使用 sed 命令处理文件

8.1 向文件中写入数据

  前面已经提到过,可以使用 w 命令向文件写入行。格式如下:

[address]w filename

  举个例子:

sed '1,2w test.txt' /etc/passwd

  该语句将数据流的第 1、2 行写入文件 test.txt 中去。

8.2 从文件中读取数据

  可以使用 r 命令来将一个文本中的数据插入到数据流中去,与普通的插入命令 i 类似,这也是对行进行操作的,命令格式如下:

[address]r filename

  filename 为要插入的文件。r 命令常结合行寻址使用,以将文本插入到指定的行后面。举个例子:

sed '3 r test.txt' /etc/passwd

  这句话将文件 test.txt 中的内容插入到数据流第三行后面去。

参考书籍:

《Linux命令行与shell脚本编程大全》 (第3版)

《Shell脚本学习指南》

Shell 基础 -- 流编辑器 sed 详解的更多相关文章

  1. Linux Shell编程与编辑器使用详解

    <Linux Shell编程与编辑器使用详解> 基本信息 作者: 刘丽霞 杨宇 出版社:电子工业出版社 ISBN:9787121207174 上架时间:2013-7-22 出版日期:201 ...

  2. Linux下的sed流编辑器命令详解

    sed是stream editor的简称,也就是流编辑器.它一次处理一行内容,处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内 ...

  3. Shell脚本学习之sed详解

    在编写shell脚本的过程中,我们经常需要使用sed流编辑器和awk对文本文件进行处理. 一.什么是sed? sed 是一种在线编辑器,它一次处理一行内容.sed是非交互式的编辑器.它不会修改文件,除 ...

  4. hbase shell基础和常用命令详解(转)

    HBase shell的基本用法 hbase提供了一个shell的终端给用户交互.使用命令hbase shell进入命令界面.通过执行 help可以看到命令的帮助信息. 以网上的一个学生成绩表的例子来 ...

  5. hbase shell基础和常用命令详解

    HBase是Google Bigtable的开源实现,它利用Hadoop HDFS作为其文件存储系统,利用Hadoop MapReduce来处理HBase中的海量数据,利用Zookeeper作为协同服 ...

  6. sed 详解

    sed 详解 1.简介 sed是非交互式的编辑器.它不会修改文件,除非使用shell重定向来保存结果.默认情况下,所有的输出行都被打印到屏幕上. sed编辑器逐行处理文件(或输入),并将结果发送到屏幕 ...

  7. (转)shell中test命令方法详解

    test命令用法.功能:检查文件和比较值 shell中test命令方法详解 原文:https://www.cnblogs.com/guanyf/p/7553940.html 1)判断表达式 if te ...

  8. 轻松学习Linux之Shell文件和目录属性详解

    轻松学习Linux之Shell文件和目录属性详解 轻松学习Linux之理解Sitcky 轻松学习Linux之理解umask 轻松学习Linux之理解SUID&SGUID 本系列多媒体教程已完成 ...

  9. shell编程之awk命令详解

    shell编程之awk命令详解 a:focus { outline: thin dotted #333; outline: 5px auto -webkit-focus-ring-color; out ...

随机推荐

  1. extern “C”的作用详解

    extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码.加上extern "C"后,会指示编译器这部分代码按C语言的进行编译,而不是C+ ...

  2. Linux系统优化之设置swappiness值提高MySQL查询性能

    对MySQL来说,操作系统层面的优化也可以值得考虑一下:就是swappiness. swappiness的大小主要对如何使用swap分区有着密切的联系. 来看一下: [root@chaofeng ~] ...

  3. SDN2017 第五次实验作业

    实验目的 1.搭建如下拓扑并连接控制器 2.下发相关流表和组表实现负载均衡 3.抓包分析验证负载均衡 实验步骤 建立以下拓扑,并连接上ODL控制器. 利用ODL下发组表.流表,实现建议负载均衡 s1组 ...

  4. 【Alpha go】Day 3!

    [Alpha go]Day 3! Part 0 · 简要目录 Part 1 · 项目燃尽图 Part 2 · 项目进展 Part 3 · 站立式会议照片 Part 4 · Scrum 摘要 Part ...

  5. windows 2012 抓明文密码方法

    windows 2012 抓明文密码方法 默认配置是抓不到明文密码了,神器mimikatz显示Password为null Authentication Id : 0 ; 121279 (0000000 ...

  6. BZOJ4894:天赋(矩阵树定理)

    Description 小明有许多潜在的天赋,他希望学习这些天赋来变得更强.正如许多游戏中一样,小明也有n种潜在的天赋,但有一些天赋必须是要有前置天赋才能够学习得到的. 也就是说,有一些天赋必须是要在 ...

  7. CentOS 7的安装

    一.引导系统之后 界面说明: Install CentOS 7 安装CentOS 7 Test this media & install CentOS  7 测试安装文件并安装CentOS  ...

  8. shiro实战系列(十四)之配置

    Shiro 被设计成能够在任何环境下工作,从最简单的命令行应用程序到最大的的企业群集应用.由于环境的多样性,使得许多配置机制适用于它的配置. 一. 许多配置选项 Shiro的SecurityManag ...

  9. Linux下RPM包的安装

    Linux下RPM包安装 二进制包(RPM包.系统默认包) RPM安装 rpm -ivh 包全名(查询依赖网址:http://www.rpmfind.net) -i(install):安装 -v(ve ...

  10. Android 对BaseAdapter做优化处理

    对于BaseAdapter相信大家都不陌生,都知道该怎样用.怎样显示数据.怎样尽可能的把每个item做的令自己满意.但问题来了:有些朋友会说我界面做的非常的漂亮,数据也显示的非常完美,但是问什么我的L ...