zoukankan      html  css  js  c++  java
  • sed流编辑器

      sed流编辑器是一行一行的处理文件内容的,正在处理的内容存放在模式空间(缓冲区)内,处理完成后按照选项的规定进行输出或文件的修改。除非使用重定向存储输出,否则文件内容不会发生改变。

      sed主要用于自动编辑一个或多个文件,简化对文件的反复操作。并且sed也支持正则表达式,如果想使用扩展正则需要添加参数-r。

    sed [选项] [附加命令] [输入文件]

    (1).选项

    -n,--quiet,--silent 取消自动打印模式空间内容
    -e [附加命令],--expression=[附加命令或脚本] 添加附加命令到程序的运行列表,允许多个-e选项
    -f [附加命令文件],--file=[附加命令文件] 读取文件的附加命令添加到程序的运行列表
    -i[后缀],--in-place[=后缀] 根据附加命令编辑文件并保存,如果存在后缀则以文件名加后缀的形式生成一个备份文件,即有后缀的为原文件,无后缀的为修改后的文件
    -c,--copy 当在-i模式下整理文件时,使用复制代替重命名(这里涉及到了文件的inode号)
    -b,--binary 以二进制模式打开文件,对CR和LFS(变更请求和日志结果文件系统)不进行特殊对待,为兼容WIN32/CYGWIN/MSDOS/EMX
    -l N,--line-length=N 为附加命令“l”指定所需的换行长度,显示形式为n-1个字符串+,最后一行没有。
    --posix 禁用所有GNU扩展
    -r,--regexp-extended 在附加命令中使用正则表达式
    -s,--separate 将文件视为独立文件,而不是单个连续的长文件流
    -u,--unbuffered 从输入文件加载最小数量的数据并更频繁地刷新输出缓冲区
    -z,--null-data 用NUL字符分隔行

    (2).附加命令

    : [标签] 为附加命令b和t设置标签
    b [标签] 跳转到设置好的标签;如果没有跟随标签则跳到附加命令末尾,结束该行的命令执行
    t [标签] 如果s///(替换命令)执行成功,则跳转到设置好的标签;如果没有跟随标签则跳到附加命令末尾,结束该行的命令执行
    T [标签] 与t相反,s///没成功时跳转到设置好的标签;如果没有跟随标签则跳到附加命令末尾,结束该行的命令执行
      示例:"s/root/xxx/;t a;s/0/1/g;:a"表示如果替换命令执行成功则不执行第二个替换命令;
         "/^root/b a;s/0/1/g;:a;s/root/xxx/g"表示如果当前行以root开头则不进行第一个替换命令,直接进行第二个替换命令
    # [附加命令] 注释,如果存在于附加命令文件则持续到当前行,如果存在于附加命令则持续到该命令结束
    {命令块} 将多条附加命令作为一个整体看待
    [附加命令1];[附加命令2];... 分号将附加命令进行分隔,允许一次编辑多条附加命令
    = 打印行号
    a [文本] 在当前行的下一行添加一行或多行文本,多行时可以使用
    转义字符进行换行
    i [文本] 在当前行的上一行添加一行或多行文本,多行时可以使用
    转义字符进行换行
    c [文本] 将当前行替换为一行或多行文本,多行时可以使用
    转义字符进行换行
      示例:"1i [文本]"表示在第一行的上一行添加文本;"i [文本]"表示在每行的上一行添加文本
    q [退出代码] 立即退出sed命令,$?获取值为设置好的退出代码
    Q [退出代码] 立即退出sed命令,$?获取值为设置好的退出代码
      注意:q和Q的区别在于,当没有取消自动打印模式空间时,q在退出前会打印当前模式空间,而Q则不会打印当前模式空间 r [文件名] 将文件内容添加到当前行的下一行 R [文件名] 文件内的每一行都作为一个单独的内容,从指定行开始,每读取一行输入文件的内容,在该行下一行添加内容   示例:"1r [文件名]"表示在输入文件的第一行的下一行添加文件所有内容;"r [文件名]"表示在输入文件的每一行的下一行添加文件所有内容;      "1R [文件名]"表示在输入文件的第一行的下一行添加文件的第一行内容,即使文件内存在多行也只运行一次;      "R [文件名]"表示从输入文件的第一行开始,每行追加文件的对应的一行内容,直到输入文件或文件内容中的一个结束;      "2,4R [文件名]"表示从输入文件的第二行到第四行,每行追加文件的第一行到第三行内容的一行内容。 d 删除模式空间 D 与d类似(有差异,但暂时不知道怎么触发) h|H 拷贝或追加模式空间的内容到内存中的缓冲区 g|G 拷贝或追加内存中的缓冲区到模式空间 l 以视觉清晰的效果显示当前行,不会取消默认打印模块,转换符会以$的形式展现 l [长度] 以视觉清晰的效果显示当前行,指定了每次打印的长度,并且转行以作为连接符(计算在长度内) n|N 将下一行读或追加到模式空间,区别在于读取会覆盖原有内容,追加则不会 p 打印模式空间所有内容 P 打印模式空间内的第一行 s/[查找内容(正则表达式)]/[替换内容]/ 尝试将查找内容与模式空间内的内容匹配,如果成功则替换成功匹配的部分。替换内容可以使用特殊字符&来指代模式空间内的匹配内容,   特殊转义字符1到9表示正则表达式中的相应匹配的子表达式。(s/[查找内容]/[替换内容]/g可以替换所有匹配到的内容) w [文件名] 将当前模式空间内容写入到指定文件中,即另存为 W [文件名] 将当前模式空间内的第一行写入指定文件中 x 交换内存中的缓冲区和模式空间的内容

    (3).实例

      说明:模式空间可以认为是sed命令每次读取文件内容的缓存区,默认一次读取文件一行。

      准备两个测试文件

    [root@youxi1 ~]# vim readFile
    root:0:0:root:123456:password
    abc:1:1:abc:password1
    xyz:2:2:abc:password2
    root:3:4:abc:pass
    [root@youxi1 ~]# vim a.txt
    12345
    67890

    1)查看readFile文件的2到4行

    [root@youxi1 ~]# sed -e "2,4p" readFile -n  //-e选项是默认选项,可以不写
    abc:1:1:abc:password1
    xyz:2:2:abc:password2
    root:3:4:abc:pass
    [root@youxi1 ~]# sed "2,4p" readFile  //如果没有-n选项,sed会默认打印模式空间的内容
    root:0:0:root:123456:password
    abc:1:1:abc:password1
    abc:1:1:abc:password1
    xyz:2:2:abc:password2
    xyz:2:2:abc:password2
    root:3:4:abc:pass
    root:3:4:abc:pass
    

    2)-i选项与-c选项,重命名与复制

    #没有-c选项时,-i选项是将原文件重命名成备份文件
    [root@youxi1 ~]# ls -i readFile  //查看readFile的inode号
    33575417 readFile
    [root@youxi1 ~]# sed -i.bak "1,2p" readFile -n  //使用-i选项编辑并保存文件
    [root@youxi1 ~]# ls -i readFile  //可以看到inode号与原文件的inode不同
    33574999 readFile
    [root@youxi1 ~]# cat readFile  //内容和原文件也不一样
    root:0:0:root:123456:password
    abc:1:1:abc:password1
    [root@youxi1 ~]# ls -i readFile.bak  //备份文件的inode号与原文件的inode号相同
    33575417 readFile.bak
    [root@youxi1 ~]# cat readFile.bak  //内容和原文件也一样
    root:0:0:root:123456:password
    abc:1:1:abc:password1
    xyz:2:2:abc:password2
    root:3:4:abc:pass
    #当-i选项与-c选项联合使用时
    [root@youxi1 ~]# sed -i.cp "1,2p" readFile.bak -n -c
    [root@youxi1 ~]# ls -i readFile.bak  //可以看到inode号和原文件相同
    33575417 readFile.bak
    [root@youxi1 ~]# cat readFile.bak  //内容与原文件不一样
    root:0:0:root:123456:password
    abc:1:1:abc:password1
    [root@youxi1 ~]# ls -i readFile.bak.cp  //备份文件的inode号与原文件的inode号不同
    34037099 readFile.bak.cp
    [root@youxi1 ~]# cat readFile.bak.cp  //内容与原文件一样
    root:0:0:root:123456:password
    abc:1:1:abc:password1
    xyz:2:2:abc:password2
    root:3:4:abc:pass
    

    3)附加命令a [文本],i [文本],c [文本]

    [root@youxi1 ~]# rm -rf readFile readFile.bak
    [root@youxi1 ~]# mv readFile.bak.cp readFile
    [root@youxi1 ~]# cat readFile
    root:0:0:root:123456:password
    abc:1:1:abc:password1
    xyz:2:2:abc:password2
    root:3:4:abc:pass
    [root@youxi1 ~]# sed "1a add" readFile  //在第一行下方添加
    root:0:0:root:123456:password
    add
    abc:1:1:abc:password1
    xyz:2:2:abc:password2
    root:3:4:abc:pass
    [root@youxi1 ~]# sed "1i add" readFile  //在第一行上一行添加
    add
    root:0:0:root:123456:password
    abc:1:1:abc:password1
    xyz:2:2:abc:password2
    root:3:4:abc:pass
    [root@youxi1 ~]# sed "1c add" readFile  //替换第一行
    add
    abc:1:1:abc:password1
    xyz:2:2:abc:password2
    root:3:4:abc:pass
    [root@youxi1 ~]# sed "1c add
    abc	123 456" readFile  //换行的转义字符
    ,Tab的转义字符	
    add
    abc 123 456
    abc:1:1:abc:password1
    xyz:2:2:abc:password2
    root:3:4:abc:pass
    

    4)附加命令=,打印行号

    [root@youxi1 ~]# sed "=" readFile
    1
    root:0:0:root:123456:password
    2
    abc:1:1:abc:password1
    3
    xyz:2:2:abc:password2
    4
    root:3:4:abc:pass
    

    5)附加命令d

    [root@youxi1 ~]# sed "1,2d" readFile
    xyz:2:2:abc:password2
    root:3:4:abc:pass
    

    6)附加命令s/[查找内容]/[替换内容]/(g)

    [root@youxi1 ~]# sed "s/root/xxx/" readFile  //替换匹配到的第一个
    xxx:0:0:root:123456:password
    abc:1:1:abc:password1
    xyz:2:2:abc:password2
    xxx:3:4:abc:pass
    [root@youxi1 ~]# sed "s/root/xxx/g" readFile  //替换匹配到的所有
    xxx:0:0:xxx:123456:password
    abc:1:1:abc:password1
    xyz:2:2:abc:password2
    xxx:3:4:abc:pass
    [root@youxi1 ~]# sed "s/a.*p/1234/" readFile  //正则匹配内容并进行替换
    root:0:0:root:123456:password
    1234assword1
    xyz:2:2:1234assword2
    root:3:4:1234ass
    [root@youxi1 ~]# sed "s/a.*p/&1234/" readFile  //正则匹配内容,保留原有的基础上进行替换
    root:0:0:root:123456:password
    abc:1:1:abc:p1234assword1
    xyz:2:2:abc:p1234assword2
    root:3:4:abc:p1234ass
    

      一样可以在s前加数字表示从第几行开始查找。

    7)-r选项,使用正则表达式匹配指定行

    [root@youxi1 ~]# sed -r "/^root/i 1234" readFile  //找到指定的行,在它的上一行添加内容
    1234
    root:0:0:root:123456:password
    abc:1:1:abc:password1
    xyz:2:2:abc:password2
    1234
    root:3:4:abc:pass
    [root@youxi1 ~]# sed "/^.*abc/{s/^.*$/&	Name/}" readFile  //可以省略-r选项
    root:0:0:root:123456:password
    abc:1:1:abc:password1   Name
    xyz:2:2:abc:password2   Name
    root:3:4:abc:pass       Name
    [root@youxi1 ~]# sed "/^.*abc/s/^.*$/&	Name/" readFile  //就连{}也可以省略,但不建议这样写,因为不方便理解
    root:0:0:root:123456:password
    abc:1:1:abc:password1   Name
    xyz:2:2:abc:password2   Name
    root:3:4:abc:pass       Name
    

    8)附加命令q、Q

    [root@youxi1 ~]# sed "/^.*abc/q" readFile  
    root:0:0:root:123456:password
    abc:1:1:abc:password1
    [root@youxi1 ~]# sed "/^.*abc/Q" readFile 
    root:0:0:root:123456:password

    9)附加命令r [文件名]、R [文件名]

    [root@youxi1 ~]# sed "/^root/r a.txt" readFile 
    root:0:0:root:123456:password
    12345
    67890
    abc:1:1:abc:password1
    xyz:2:2:abc:password2
    root:3:4:abc:pass
    12345
    67890
    [root@youxi1 ~]# sed "/^root/R a.txt" readFile  
    root:0:0:root:123456:password
    12345
    abc:1:1:abc:password1
    xyz:2:2:abc:password2
    root:3:4:abc:pass
    67890

    10)附加命令n、N、p、P、w、W

      首先一定要了解n(读取下一行到模式空间)、N(追加下一行到模式空间),以及默认打印模式空间的触发动作(预备读取下一行,结束sed命令)。注意:读取和追加到模式空间的行,sed命令就不再读取了。

    [root@youxi1 ~]# sed "n;p" readFile 
    root:0:0:root:123456:password  //预备执行附加命令n,触发默认打印当前模式空间。n执行完成后,模式空间内容是第二行内容
    abc:1:1:abc:password1  //执行附加命令p,打印当前模式空间,模式空间内容不变
    abc:1:1:abc:password1  //sed命令预备读取下一行,触发默认打印当前模式空间。读取下一行完成后,模式空间内容是第三行
    xyz:2:2:abc:password2  //预备执行附加命令n,触发默认打印当前模式空间。n执行完成后,模式空间内容是第四行
    root:3:4:abc:pass  //执行附加命令p,打印当前模式空间,模式空间内容不变
    root:3:4:abc:pass  //sed命令结束,打印当前模式空间(此举是清空模式空间?)
    [root@youxi1 ~]# sed "N;p" readFile   
    root:0:0:root:123456:password
    abc:1:1:abc:password1  //执行附加命令N,模式空间内容为第一行和第二行;执行附加命令p,打印当前模式空间
    root:0:0:root:123456:password
    abc:1:1:abc:password1  //sed命令预备读取下一行,触发默认打印当前模式空间。读取下一行完成后,模式空间内容是第三行
    xyz:2:2:abc:password2
    root:3:4:abc:pass  //执行附加命令N,模式空间内容由第三行变为第三第四行;执行附加命令p,打印当前模式空间
    xyz:2:2:abc:password2
    root:3:4:abc:pass  //sed命令结束,打印当前模式空间(此举是清空模式空间?)
    

      接着了解p(打印当前模式空间)和P(打印模式空间内的第一行)。在了解n和N的情况下,还是很好理解的。

    [root@youxi1 ~]# sed "N;p" readFile -n
    root:0:0:root:123456:password
    abc:1:1:abc:password1
    xyz:2:2:abc:password2
    root:3:4:abc:pass
    [root@youxi1 ~]# sed "N;P" readFile -n 
    root:0:0:root:123456:password
    xyz:2:2:abc:password2
    

      最后是w(保存当前模式空间到指定文件)和W(保存当前模式空间内的第一行到指定文件),和p、P的区别就是不打印,直接保存到文件中。了解了p和P,那么这两个也是很简单的。

    [root@youxi1 ~]# sed "N;w b.txt" readFile -n
    [root@youxi1 ~]# sed "N;W c.txt" readFile -n
    [root@youxi1 ~]# cat b.txt
    root:0:0:root:123456:password
    abc:1:1:abc:password1
    xyz:2:2:abc:password2
    root:3:4:abc:pass
    [root@youxi1 ~]# cat c.txt
    root:0:0:root:123456:password
    xyz:2:2:abc:password2
    

    (4).sed增删改查

      sed命令比较常用的就是增删改查四项,“增”可以使用附加命令a [文本]、i [文本]、r [文件名]和R [文件名],“删”可以使用附加命令d,“改”可以使用附加命令c [文本]和s/[查找内容]/[替换内容]/,“查”可以使用-r选项以及附加命令p

  • 相关阅读:
    js实现全选反选功能
    seajs笔记
    延迟加载图片
    JavaScript 数组基本操作
    图片上传,头像上传
    命令模式
    动态加载js css 插件
    发布-订阅模式
    js 切换全屏
    JavaScript 经典之一 闭包
  • 原文地址:https://www.cnblogs.com/diantong/p/11725438.html
Copyright © 2011-2022 走看看