一、功能简介

sed(Stream EDitor),是一种流文件编辑器,其特点为:

1、非交互式。处理文件时,把当前处理的行存储在临时缓冲区(称为“模式空间”(Pattern Space))中,即它是基于模式匹配过滤及修改文本。

2、逐行处理,sed 命令在缓冲区中一次处理一行内容,处理完成后,把缓冲区的内容送往屏幕,接着处理下一行,直到文件末尾。

正常情况下,sed命令所做的处理只是把操作结果(包括打印、删除等)输出到当前终端屏幕,而并不会对原始文件做任何更改。若希望直接修改文件内容,应添加选项 -i 。为了避免生产环境中因误操作导致系统故障,使用时要谨慎。

sed 主要用来编辑一个或多个文件,简化对文件的反复操作(如:输出、删除、替换、复制、剪切、导入、导出等各种操作)或者用来编写转换程序等。

二、语法格式

格式1:前置命令 | sed [选项] '[定址符]处理动作’

格式2:sed [选项] '[定址符]处理动作’文件 [input-file]

其中:处理动作可以由-e指定多个处理动作,input-file为输入文件,可指定多个。

三、语法说明

1、选项说明

  • -i:直接修改文件内容,而不是输出到终端。
  • -n:安静模式,屏蔽默认输出(全部文本),只有经过sed特殊处理的那一行才会被列出来。
  • -e :指定sed动作,可以由多个-e指定多个动作。
  • -r:启用扩展的正则表达式,若与其他选项一起使用,应作为首个选项。
  • -f :直接将sed的动作写在一个文件内,-f filename则可以运行filename 内的sed动作。
  • --help:显示帮助。
  • --version:显示版本。
  • -{}:可组合多个命令,以分号分隔。

2、动作说明

​ [n1[,n2]] function

  • 其中[n1[,n2]]称为定址符,用来定义需要操作的文本,如指定处理的起、止行数。

  • n1, n2 不见得会存在,一般代表“选择进行动作的行数”,举例来说,如果我的动作是需要在 10 到 20 行之间进行,则写作“10,20动作行为”。

  • 地址可表示为文本的“行号”,或者用来匹配的“/正则表达式/”

  • 省略定址符时,默认逐行处理全部文本。

​ fuction为编辑指令,可以为增删改查等指令

  • a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~
  • c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
  • d :删除,因为是删除啊,所以 d 后面通常不接任何内容;
  • i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
  • p :打印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行
  • s :替换,通常这个s的动作可以搭配正规表示法!例如 1,20s/old/new/g。

四、典型示例

sed命令详解+示例_ip地址

替换担任的分隔“/”,可改用其他字符,如#、&等,便于修改文件路径

示例:把/bin/bash替换为/sbin/sh (/etc/passwd)

sed "s/\/bin\/bash/\/sbin\/sh/" /etc/passwd
或者
sed "s#/bin/bash#/sbin/sh#" /etc/passwd

sed命令详解+示例_sed_02

处理多行文本:修改后的文本有多行时,以换行符\n分隔,或使用\强制换行

示例:修改主机名配置文件

1)确认修改前的配置 # cat /etc/sysconfig/network

2)使用sed修改主机名配置所在行的内容(c整行替换)

sed  '/^HOSTNAME/cHOSTNAME=mysvr.tarena.com' /etc/sysconfig/network 

示例:修改hosts文件,添加新的记录

1)确认修改前的配置 # cat /etc/hosts

2)使用sed修改hosts文件,添加两行新纪录(a追加)

sed  -i  '$a192.168.4.5  svr5.tarena.com svr5\
> 119.75.217.56  www.baidu.com' /etc/hosts

常见处理操作示例:

sed命令详解+示例_sed_03sed命令详解+示例_正则表达式_04sed命令详解+示例_定址_05

文件导入导出操作

基本动作:

  • r 动作应结合-i选项才会存入,否则只输出
  • w 动作以覆盖的方式另存为新文件

sed命令详解+示例_ipad_06

sed -n ‘/^XX/w d.txt’ reg.txt 与 sed -n ‘/^XX/p d.txt’ reg.txt > d.txt操作效果相同

换行:****n和N的区别

sed命令详解+示例_sed_07

n:打印当前模式空间内容,然后读取下一行并替代当前模式空间的内容。如果读取不到下一行sed则会不运行之后的命令。

sed命令详解+示例_定址_08

​ 上面命令过程是这样:

  1. 先读取第一行进模式空间(以后简称为1)

  2. 执行命令n,过程如下

  3. 打印1到输出

  4. 读取2并覆盖到模式空间

  5. 执行命令d,过程如下

  6. 删除模式空间的内容

  7. 立即执行下一循环(d命令在运行后会直接执行下一循环,所以它并不会执行之后的命令和打印模式空间,具体d介绍会留在下次分享)

  8. 按照上面的流程循环执行…….直到读取到11(最后一行),11的具体过程如下

  9. 读取11进模式空间

  10. 运行命令n,不过读取不到下一行

  11. 因为读不到,所以sed退出所有的命令,也就是说它不会执行命令d

  12. 加回换行符并打印模式空间的内容到输出,当前模式空间内容为11,所以输出11

  13. 已经是文件尾,sed结束运行

N:读取下一行并且附加到当前模式空间内,如果读取不到下一行sed则会不运行之后的命令。

sed命令详解+示例_ip地址_09

​ 上面命令过程是这样:

  1. 读取1进模式空间

  2. 执行命令N

  3. 读取2并附加到模式空间,当前模式空间内容为“1\n2”

  4. 执行命令a—

  5. 在模式空间后附加一行‘—’当前模式空间内容为“1\n2\n—"

  6. 打印模式空间内容

  7. 循环执行直到读取11进模式空间,11的具体过程如下

  8. 读取11进模式空间

  9. 执行命令N,不过读取不到下一行

  10. 因为读不到,所以sed退出所有的命令,也就是说它不会执行命令a

  11. 加回换行符并打印模式空间的内容到输出,当前模式空间内容为11,所以输出11

  12. 已经是文件尾,sed结束运行。

五、综合运用

  1. 删除文件中每行的第二个、最后一个字符

    分两次替换操作,第一次替换掉第2个字符,第二次替换掉最后一个字符:

    sed 's/.//2;s/.$//' nssw.txt 
    
  2. 将文件中每行的第一个、第二个字符互换

    每行文本拆分为“第1个字符”、“第2个字符”、“剩下的所有字符”三个部分,然后通过替换操作重排顺序为“2-1-3”:

    sed -r 's/^(.)(.)(.*)/\2\1\3/' nssw.txt
    
  3. 将第一个字符与最后一字符对调:

    sed -r “s/^(.)( .*)(.)$/\3\2\1/” nssw.txt
    
  4. 删除文件中所有的数字、行首的空格

    sed -r 's/[0-9]+//g;s/^( )+//' nssw2.txt
    
  5. 为文件中每个大写字母添加括号

     sed 's/[A-Z]/(&)/g' nssw.txt        //使用“&”可调用s替换操作中的整个查找串 或者  sed -r "s/([A-Z])/(\1)/g"  nssw.txt
    
  6. 修改默认运行级别

    sed -i '/^id:/s/3/5/' /etc/inittab            //将默认运行级别修改为5grep "^id:" /etc/inittab                      //确认修改结果
    
  7. 修改IP地址(网段):修改IP地址的网段部分,主机地址不变。

    直接修改网卡eth0的配置文件,检查原有的配置内容:

    cat /etc/sysconfig/network-scripts/ifcfg-eth0IPADDR=192.168.4.4
    

    若希望将IP地址192.168.4.4修改为172.16.16.4,则应该定位到“IPADDR”所在的行,执行相应的替换(仅测试,尚未修改):

    sed '/^IPADDR/s/192.168.4.4/172.16.16.4/' \/etc/sysconfig/network-scripts/ifcfg-eth0 | grep "^IPADDR"
    

    要求只修改网段地址时,可以利用扩展正则表达式的 \1、\2、……等调用,分别对应此前第1个、第2个、…… 以 ()包围的表达式所匹配的内容。

    所以上述操作可以改为如下(启用扩展匹配应添加 -r 选项):

    sed -r -i '/^IPADDR/s/192.168.4.(.*)/172.16.16.\1/' \/etc/sysconfig/network-scripts/ifcfg-eth0
    

    确认修改结果:

    grep "^IPADDR" /etc/sysconfig/network-scripts/ifcfg-eth0
    
  8. 调整httpd服务配置,更改网站根目录

    由于需要替换的字符串中有 / ,为了避免与sed替换操作的分隔混淆,可以使用其他字符作为替换分隔,比如可改用“s#old#new#”的方式实现替换:

    sed -i 's#/var/www/html#/opt/wwwroot#' /etc/httpd/conf/httpd.confgrep "^DocumentRoot" /etc/httpd/conf/httpd.confDocumentRoot "/opt/wwwroot"
    
  9. 修改/etc/hosts

    sed -i ‘1a 1.1.1.1 域名’ /etc/hosts
    
  10. 打印奇、偶数

    sed命令详解+示例_sed_10

  11. 打印行号sed命令详解+示例_定址_11

  12. 将行号和内容一行显示

    sed命令详解+示例_定址_12

    N代表 将第二行追加到第一行后面表示为1\n2 。这样将 \n 替换成 空格就行了 s/\n/ /