Linux基础 sed命令详解

概述


sed是一个流编辑器(Stream EDitor)。主要用于自动编辑一个或多个文件简化对文件的反复操作编写转换程序等。本文主要讲述了:

  • sed工作原理

  • sed命令格式及常用选项

  • 应用实例

  • 高级编辑命令

sed工作原理


sed命令运行过程中维护着两个缓冲区,一个是活动的“模式空间(pattern
space
)”,另一个是起辅助作用的“暂存缓冲区(holding space)”。sed每次处理一行内容,整个文件像流水一样被逐行处理然后逐行输出。处理时,把当前处理的行存储在”模式空间”(pattern space ),接着用sed 命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。工作过程如下图所示:

1470804204883479.gif

一般情况下暂存缓冲区是用不到的,但有特殊的命令可以在模式空间与暂存缓冲区之间交换数据,由于sed对文本的所有操作都是在模式空间里进行的,所以,默认情况下,sed不会对原文件内容修改,处理后的所有输出行都被打印到屏幕上,除非你使用重定向存储输出。

sed命令格式及常用选项


用法:

sed [OPTION]... PATTERN [input-file]...

OPTION:

-n:不输出模式空间中的内容至屏幕;
-e script, --expression=script:多点编辑;
-f /PATH/TO/SED_SCRIPT_FILE   每行一个编辑命令;
-r,--regexp-extended:支持使用扩展正则表达式;
-i[SUFFIX], --in-place[=SUFFIX]:直接编辑原文件 ;
     #一般不建议-i,如需进行文件修改,强烈建议先备份,即-i.CHAR。(.CHAR为备份文件后缀名,可自定义。)

PATTERN:

 PATTERN是一组特定的sed命令(很多时候也称之SCRIPT),一定要被包含在一对单引号中,以免被shell解释,其格式如下:

'[address-range]sed-command'

address-range是指要处理的行的范围,又叫地址界定;

sed-command是一个sed命令,用来对指定的行进行处理。

地址界定:

1. 空地址:对全文进行处理;
2. 单地址:
    n:指定第n行;
    /pattern/:被此模式所匹配到的每一行;
3. 地址范围
    n,m:第n行开始至第m行
    n,+m:第n行开始,至后面的m行
    n,/pat1/:第n行开始,至第一次匹配pat1的行
    /pat1/,/pat2/:第一个匹配pat1的行开始,至第一个匹配pat2的行
    $:最后一行;
4. ~步进:
    n~m:第n行开始,每次步进m行
    1~2:所有奇数行
    2~2:所有偶数行

编辑命令:

d:删除;
p:显示模式空间中的内容;
a  \text:在行后面追加文本“text”,支持使用\n实现多行追加; 
i  \text:在行前面插入文本“text”,支持使用\n实现多行插入; 
c  \text:把匹配到的行替换为此处指定的文本“text”;
w /PATH/TO/SOMEFILE:保存模式空间匹配到的行至指定的文件中;
r  /PATH/FROM/SOMEFILE:读取指定文件的内容至当前文件被模式匹配到的行后面;文件合并;
=:为模式匹配到的行打印行号;
!:条件取反;
  地址定界!编辑命令;
s///:查找替换,其分隔符可自行指定,常用的有s@@@, s###等;
  替换标记:
    g:全局替换;
    w /PATH/TO/SOMEFILE:将替换成功的结果保存至指定文件中;
    p:显示替换成功的行;
{COMMANDS}:可以把多个命令括起来,用来处理单个地址或者地址范围。
  sed -n '5,9p;='
  sed -n '5,9{p;=}'

高级编辑命令:

h:把模式空间中的内容覆盖至保持空间中;
H:把模式空间中的内容追加至保持空间中;
g:把保持空间中的内容覆盖至模式空间中;
G:把保持空间中的内容追加至模式空间中;
x:把模式空间中的内容与保持空间中的内容互换;
n:覆盖读取匹配到的行的下一行至模式空间中;
N:追加读取匹配到的行的下一行至模式空间中;
d:删除模式空间中的行;
D:删除多行模式空间中的所有行;

1470833317496604.png

应用实例


不同的系统环境或sed版本的命令实现有可能有微改动,但是用法基本不变,下列演示基于如下环境中进行:

  •               OS:    CentOS Linux release 7.2.1511 (Core)

  • sed version:    sed (GNU sed) 4.2.2

演示文件1:

1470915711997324.png

[root@IP70-CentOS7 ~]# >>sed '2p' /etc/passwd   #打印第二行

1470915279331988.png

[root@IP70-CentOS7 ~]# >>sed -n '2p' /etc/passwd    #仅打印第二行

1470915389611930.png

[root@IP70-CentOS7 ~]# >>sed -n '1,4p' /etc/passwd    #仅打印第1到第4行(范围地址)

Image 20160811194018.png

[root@IP70-CentOS7 ~]# >>sed -n '/root/p' /etc/passwd    #仅打印匹配root的行(单地址模式匹配)

1470915929120560.png

[root@IP70-CentOS7 ~]# >>sed -n '2,/root/p' /etc/passwd    #仅打印从第2行开始,至匹配root的行(范围地址)

1470916193897319.png

[root@IP70-CentOS7 ~]# >>sed '/root/a\superman' /etc/passwd    #sed-command演示:a:匹配行后追加文本

1470916991349380.png

[root@IP70-CentOS7 ~]# >>sed '/root/i\superman' /etc/passwd    #sed-command演示:i:匹配行前插入文本

1470917171936554.png

[root@IP70-CentOS7 ~]# >>sed '/root/c\superman' /etc/passwd    #sed-command演示:c:匹配行替换成指定文本

Image 20160811200802.png

[root@IP70-CentOS7 ~]# >>sed -n 's/root/&superman/p' /etc/passwd    #sed-command演示:s:查找root,替换成&superman(&代表引用匹配查找的内容)

1470917900411086.png

[root@IP70-CentOS7 ~]# >>sed  's/root/superman&/g' /etc/passwd    #sed-command演示:s:查找替换,对比上个示例,p仅替换每行第一个匹配的文本,g就进行全局匹配

1470917917783416.png

演示文件2:

1470918315995520.png

[root@IP70-CentOS7 ~]# >>sed -n '/^$/=' testfile    #sed-command演示:= 显示行号(^$ 空行)

1470918449906653.png

[root@IP70-CentOS7 ~]# >>sed -n -e '/^$/p' -e '/^$/=' testfile     #选项 -e的引用

Image 20160811203502.png

[root@IP70-CentOS7 ~]# >>sed  '/^$/d' testfile    #sed-command演示:d 删除匹配的行

1470919019303625.png

[root@IP70-CentOS7 ~]# >>sed  '1,10d' testfile    #范围地址第1至第10行, sed-command: d删除行

1470919100403990.png

[root@IP70-CentOS7 ~]# >>sed -i.bak 's/^test.*$/deleted/g' testfile    
 #选项-i的应用,如需进行文件修改,强烈建议先备份,即-i.CHAR。(.CHAR为备份文件后缀名,可自定义。)

1470919979292691.png

1470919996990277.png

高级编辑命令


[root@IP70-CentOS7 ~]# >>sed -n 'n;p' testfile.bak     #打印偶数行

Image 20160812092008.png

[root@IP70-CentOS7 ~]# >>sed  '1!G;h;$!d' testfile.bak     #倒序显示行,相当于tac命令

1470964912771805.png

[root@IP70-CentOS7 ~]# >>sed  '$!N;$!d' testfile.bak

Image 20160812092355.png

[root@IP70-CentOS7 ~]# >>sed  '$!N' testfile.bak

Image 20160812092909.png

[root@IP70-CentOS7 ~]# >>sed  '$!d' testfile.bak

Image 20160812092927.png

[root@IP70-CentOS7 ~]# >>sed  'G' testfile.bak

Image 20160812093053.png

[root@IP70-CentOS7 ~]# >>sed  'n;d' testfile.bak

Image 20160812093209.png

结束语


个人认为相较于grep而言,sed查找匹配行后可进行更多的命令操作,提供的d删除和s替换功能更是如虎添翼。掌握一项技能在于多用,在理解上述演示的前提下,在实际应用中纵向深挖,与人分享探讨。

由于初学Linux,限于本人水平有限,文中难免错误纰漏。欢迎各位看官不吝指教、讨论相关技术。谢谢。

联系我:jacky18676887374@aliyun.com

原创文章,作者:昭其,如若转载,请注明出处:http://www.178linux.com/32451

(0)
上一篇 2016-08-12 14:45
下一篇 2016-08-12 16:06

相关推荐

  • MongoDB复制集及数据分片详解

    前言 MongoDB是一个由C++语言编写的基于分布式文件存储的数据库,是当前NoSQL数据库中比较热门的一种,旨在为Web应用提供可扩展的高性能数据存储解决方案。本文介绍MongoDB复制集及数据分片。 MongoDB 简介 MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。支持的数据结构非常松散,…

    Linux干货 2015-07-15
  • wordpress和discuz的负载均衡(lvs-nat)

    实验目的:利用lvs-nat模型实现wordpress和discuz的负载均衡 实验要求:客户端访问wordpress或Discuz服务时,无论被调度至哪台RS上,其会话和访问的页面都应保持一致; 实验环境:一台server用作VS(需要两块网卡,eth1连接内部网络,eth0连接外部网络),两台server用作RS,一台server用于部署mysql、NF…

    2017-05-13
  • shell中的if else语句与文件查找find浅析

    shell中的if else语句与文件查找find浅析    上篇文章中我们讲述了shell脚本编程的初步入门,其中讲到了shell编程中的顺序执行,顺序执行时一种简单的小脚本,如果在编辑脚本的时候遇到要做出条件判断执行的时候要怎么办呢?我们学习过if之后你会发现这会很简单。if 语句通过关系运算符判断表达式的真假来决定执行哪个分支。 S…

    Linux干货 2016-08-16
  • Lvm基本应用,扩展及缩减实现

    什么是LVM LVM是Logical Volume Manager的简写。其是Linux环境下对磁盘分区进行管理的一种机制。LVM由Heinz Mauelshagen在Linux 2.4内核上实现。其主要作用是在不损坏磁盘数据的情况下对磁盘空间进行增加,缩减。LVM的做法是将几块物理硬盘通过软件的方式组合成一块空间相对大的Volume Group,简称VG,…

    Linux干货 2016-09-08
  • 如何将迁移home到独立分区中

        背景(centos7中):         由于在刚开始学习linux时磁盘分配追求简单,只是把一个磁盘简单的分了3个分区。现在,因用户数据增多、磁盘空间变少、当数据撑满磁盘时,会导致系统崩溃。为防止此种情况的发生我必须把把根下的/home 目录迁移出 来独立分…

    2017-08-10
  • find 的使用及练习

    find是个使用频率比较高的命令。常常用它在系统特定目录下,查找具有某种特征【名字类型属主权限等】的文件。find命令的格式: find  [-path ..] -options [-print -exec -ok] path:要查找的目录路径。 ~ 表示$HOME目录 . 表示当前目录 / 表示根目录 -print :表示将结果输出到标准输出-e…

    Linux干货 2017-06-11