linux文本处理三剑客之sed,原来只需要掌握这些!!!

Posted 涤生手记

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux文本处理三剑客之sed,原来只需要掌握这些!!!相关的知识,希望对你有一定的参考价值。

 前言:

shell脚本最常见的一个用途就是处理文本文件。检查日志文件、读取配置 文件、处理数据元素,shell脚本可以帮助我们将文本文件中各种数据的日常处理任务自动化。但仅靠shell脚本命令来处理文本文件的内容有点力不从心的。如果想在shell脚本中处理任何类型的数据,掌握sedgawk工具可以达到事半功倍的效果。企业开发中常用,高阶命令。

一、sed编辑器基本了解

sed 编辑器被称作 流编辑器 stream editor),和普通的交互式文本编辑器恰好相反。流编
辑器会在编辑器处理数据之前基于预先提供的一组规则来编辑数据流。 可以根据命令来处理数据流中的数据,这些命令要么从命令行中输入,要么存储 在一个命令文本文件中。
sed编辑器执行流程大致如下:
  1. 一次从输入中读取一行数据。
  2. 根据所提供的编辑器命令匹配数据。
  3. 按照命令修改流中的数据。
  4. 将新的数据输出到STDOUT。

核心讲解:

在流编辑器将所有命令与一行数据匹配完毕后,它会读取下一行数据并重复这个过程。在流
编辑器处理完流中的所有数据行后,它就会终止。
由于命令是按顺序逐行给出的, sed 编辑器只需对数据流进行一遍处理就可以完成编辑操作。
这使得 sed 编辑器要比交互式编辑器快得多,你可以快速完成对数据的自动修改。

有了上面核心理论的了解,下面我们就可以对sed进行实操演练了:

sed 使用的语法格式:

sed options script file

常用参数罗列:

  • -e script 在处理输入时,将script中指定的命令添加到已有的命令中
  • -f file 在处理输入时,将file中指定的命令添加到已有的命令中
  • -n 不产生命令输出,使用print命令来完成输出

重点说明:

script 参数指定了应用于流数据上的单个命令。如果需要用多个命令,要么使用 -e 选项在
命令行中指定,要么使用 -f 选项在单独的文件中指定。有大量的命令可用来处理数据。

1.1 在终端命令行使用单条sed命令

默认情况下, sed 编辑器会将指定的命令应用到 STDIN 输入流上。这样你可以直接将数据通
过管道输入 sed 编辑器处理。
演示案例:
单行文本修改:

 如截图中所见,这个例子在sed编辑器中使用了s命令。s命令会用斜线间指定的第二个文本字符串来替换第 一个文本字符串模式。在本例中是big test替换了test

整个文本修改:

 核心讲解:

在运行上面的例子时,结果都是立即就会显示出来的。这就是使用 sed编辑器的强大之处。我们可以同时对文本数据做出多处修改,而需要操作的时间是及其短暂的。需要注意的一点的是,sed编辑器并不会修改原来文本文件的数据。它只会将修改后的数据发送到STDOUT,我们可以查看源文本的数据依旧保持不变。

 1.2 在命令行使用多个sed 命令

要在 sed 命令行上执行多个命令时,只要用 -e 选项就可以了。

 操作演示:

 操作详解:

两个命令都作用到文件中的每行数据上。命令之间必须用分号隔开,并且在命令末尾和分号 之间不能有空格。还有一种方式我们使用的很少,就是用shell中的次提示符来分隔命令,如下截图:

 1.3 从文件中读取编辑器命令

有时候我们有大量要处理的sed命令,此时我们就可以命令放在一个脚本文件里,文件通常以.sed 结尾,使用中我们只需要应用 -f 参数,就可以来读取文件中命令:

核心解说: 

如上图,sed编辑器知道每行都是一条单独的命令。 跟在命令行输入命令一样,sed编辑器会从指定文件中读取命令,并将它们应用到数据文件中的 每一行上。同样达到了对文本处理的效果。

二、sed编辑器工作中经常的使用

成功使用 sed 编辑器的关键在于掌握其各式各样的命令和格式,它们能够帮助你定制文本编
辑行为。本节将介绍一些可以集成到脚本中基本命令和功能。上面章节我们已经懂得了如何用s 命令( substitute )来在行中替换文本。这个命令还有另外一些选 项能让事情变得更为简单。

2.1. 替换标记

实例展示:

上图中可以看到替换命令在替换多行中的文本时能正常工作,但默认情况下它只替换每行中出现的第一处。 要让替换命令能够替换一行中不同地方出现的文本必须使用替换标substitutionflag),替换标记会在替换命令字符串之后设置。

替换标记分类:

  • 数字,表明新文本将替换第几处模式匹配的地方;
  • g,表明新文本将会替换所有匹配的文本;
  • p,表明原先行的内容要打印出来;
  • w file,将替换的结果写到文件中。
在第一类替换中,可以指定 sed 编辑器用新文本替换第几处模式匹配的地方。

 

 对比一以上两图,我们可以得出结论:

将替换标记指定为 2 的结果就是: sed 编辑器只替换每行中第二次出现的匹配模式。 g替换标
使你能替换文本中匹配模式所匹配的每处地方。 
p 替换标记会打印与替换命令中指定的模式匹配的行。这通常会和 sed -n 选项一起使用。
-n 选项将禁止 sed 编辑器输出。但 p 替换标记会输出修改过的行。将二者配合使用的效果就是
只输出被替换命令修改过的行。
如下效果图:

w 替换标记会产生和p替换标记相同的输出,不同的是w会将输出保存到指定文件中。
如下效果图:

 2.2 替换字符

有时我们会在文本字符串中遇到一些不太方便在替换模式中使用的字符。 Linux 中一个常见的
例子就是正斜线( / )。 替换文件中的路径名会比较麻烦。
比如下面,如果想用C shell替换/etc/passwd文件中的bash shell,需要使用如下方式:

 上面我们可以发现,由于正斜线通常用作字符串分隔符,因而如果它出现在了模式文本中的话,必须用反斜线来 转义。这通常会带来一些困惑和错误。 要解决这个问题,sed编辑器允许选择其他字符来作为替换命令中的字符串分隔符,下例中我们就是使用感叹号用作字符串分隔符。

 2.3 sed 的寻址操作

sed 的寻址模式分为两种:

  1. 以数字形式表示行区间
  2. 用文本模式来过滤出行

两种寻址的语法格式是相同的,sed编辑器会将指定的每条命令作用到匹配指定地址的行上。

[address]command
或者是将特定地址的多个命令分组:
address {
command1
command2
command3
}

2.3.1 数字寻址(常用的方式)

        当使用数字方式的行寻址时,可以用行在文本流中的行位置来引用。sed 编辑器会将文本流中的第一行编号为1 ,然后继续按顺序为接下来的行分配行号。 在命令中指定的地址可以是单个号,或是用起始行号、逗号以及结尾行号指定的一定区间范围内的行。
演示截图:
a.指定行号

b.行地址区间

 c.如果想将命令作用到文本中从某行开始的所有行,可以用特殊地址$.

 2.3.2 使用文本模式过滤器(不常用)

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

必须用正斜线将要指定的pattern封起来。sed编辑器会将该命令作用到包含指定文本模式的行上。 

如下面给的示例:修改用户Samantha的默认shell,可以使用sed命令。

 核心详解:

该命令只作用到匹配文本模式的行上。虽然使用固定文本模式能帮你过滤出特定的值,就跟 上面这个用户名的例子一样,但其作用难免有限。sed 编辑器在文本模式中采用了一种称为 正则 表达式( regular expression )的特性来帮助你创建匹配效果更好的模式。

 2.3.3 命令组合使用

如果需要在单行上执行多条命令,可以用花括号将多条命令组合在一起。 sed 编辑器会处理
地址行处列出的每条命令。

两条命令都会作用到该地址上。同样,也可以在一组命令前指定一个地址区间。 

2.4 删除行 

文本替换命令不是 sed 编辑器唯一的命令。如果需要删除文本流中的特定行,可以用删除命令。
删除命令d名副其实,它会删除匹配指定寻址模式的所有行。使用该命令时要特别小心,如 果你忘记加入寻址模式的话,流中的所有文本行都会被删除。

2.4.1 指定地址删除

 2.4.2 指定特定区间

 2.4.3 通过特殊的文件结尾字符

 笔记重点:

记住,sed编辑器不会修改原始文件。你删除的行只是从sed编辑器的输出中消失了。原始
文件仍然包含那些“删掉的”行。

2.5  插入和附加文本

和其他编辑器类似,sed编辑器允许向数据流插入和附加文本行。两个操作的区别可能比较让人费解:

  • 插入(insert)命令(i)会在指定行前增加一个新行;
  • 附加(append)命令(a)会在指定行后增加一个新行。

这两条命令的费解之处在于它们的格式。它们不能在单个命令行上使用。你必须指定是要将行插入还是附加到另一行。格式如下:

sed '[address]command  new line'

注意:new line 中的文本将会出现在 sed 编辑器输出中你指定的位置。记住,当使用插入命令时, 文本会出现在数据流文本的前面。

 2.5.1 指定行数插入数据

2.6 修改行 

修改( change )命令允许修改数据流中整行文本的内容。它跟插入和附加命令的工作机制
一样,你必须在 sed 命令中单独指定新行。

 2.7 转换命令

转换( transform )命令( y )是唯一可以处理单个字符的 sed 编辑器命令。转换命令格式
如下:
[ address ] y / inchars / outchars /
转换命令会对 inchars outchars 值进行一对一的映射。 inchars 中的第一个字符会被转 换outchars 中的第一个字符,第二个字符会被转换成 outchars 中的第二个字符。这个映射过程会一直持续到处理完指定字符。如果inchars outchars 的长度不同,则 sed 编辑器会产生一 条错误消息。
操作示例:

 如图中输出中看到的,inchars模式中指定字符的每个实例都会被替换成outchars模式中 相同位置的那个字符。 转换命令是一个全局命令,也就是说,它会文本行中找到的所有指定字符自动进行转换,而不会考虑它们出现的位置。

sed 编辑器转换了在文本行中匹配到的字符 1 的两个实例。无法限定只转换在特定地方出现 的字符。
如下例:

2.8 使用 sed 处理文件

替换命令包含一些可以用于文件的标记。还有一些 sed 编辑器命令也可以实现同样的目标,
不需要非得替换文本。

2.8.1 写入文件

w 命令用来向文件写入行。该命令的格式如下:
[ address ]w filename
filename 可以使用相对路径或绝对路径,但不管是哪种,运行 sed 编辑器的用户都必须有文
件的写权限。地址可以是 sed 中支持的任意类型的寻址方式,例如单个行号、文本模式、行区间
或文本模式。
下面的例子是将数据流中的前两行打印到一个文本文件中:

 2.8.2 2. 从文件读取数据

上面已经了解了如何在 sed 命令行上向数据流中插入或附加文本。读取( read )命令( r )允
许你将一个独立文件中的数据插入到数据流中。
读取命令的格式如下:
[ address ]r filename
filename 参数指定了数据文件的绝对路径或相对路径。你在读取命令中使用地址区间,只
能指定单独一个行号或文本模式地址。 sed 编辑器会将文件中的文本插入到指定地址后。

 后记:

虽然 shell 脚本本身完成很多事情,但单凭 shell 脚本通常很难处理数据。 Linux 提供了两个方便
的工具来帮助处理文本数据。作为一款流编辑器, sed 编辑器能在读取数据时快速地自动处理数 据。必须给sed 编辑器提供用于处理数据的编辑命令。
下篇我们将会持续讲到awk。。。。

 

以上是关于linux文本处理三剑客之sed,原来只需要掌握这些!!!的主要内容,如果未能解决你的问题,请参考以下文章

Linux文本处理三剑客之sed

Linux运维文本处理三剑客之sed命令

性能工具之linux三剑客awkgrepsed详解

linux三剑客之sed

linux文本三剑客之sed命令详解

Linux文本处理三剑客之---sed