1. Sed 简介

sed 是Stream Editor(流编辑器)的缩写,是操作、过滤和转换文本内容的强大工具。常用功能有增删改查,过滤,取行。

 

sed 是一种新型的,非交互式的编辑器

它能执行与编辑器vi 和 ex 相同的编辑任务。

sed 编辑器没有提供 交互式使用方式,使用者只能在命令行输入编辑命令、指定文件名,然后在屏幕上查看输出

sed 编辑器没有破坏性,它不会修改文件,除非使用 shell 重定向 来保存输出结果。

默认情况下,所有的输出行都被打印到屏幕上。

# 查看sed软件版本
[root@oldboy ~]# sed --version
GNU sed version 4.2.1

2. sed 工作过程

sed 编辑器逐行处理文件(或输入),并将输出结果发送到屏幕。

sed 的命令就是在 vi 和 ed/ex 编辑器中见到的那些。

sed 把当前正在处理的行 保存在一个临时缓存区,这个缓存区称为模式空间临时缓冲

sed 处理完模式空间中的行后(即在该行上执行 sed 命令后),就把该行发送到屏幕上(除非之前有命令删除这一行或取消打印操作)。

sed 处理完输入文件的最后一行后,sed 便结束运行

sed 把每一行都存在临时缓存区,对这个副本进行编辑,所以不会修改或破坏源文件。

概括流程

sed软件从stdin读取加载一行,判断是否符合执行操作条件:

  • 若不符合,则读取下一行,将下一行文本加载到模式空间;
  • 若符合条件,则执行相应的命令操作,就将该行内容发送到屏幕上。

逐行进行,直至最后一行,结束。

 

3. Sed 命令格式

sed命令行格式为:sed [选项] 'command' 输入文本

    sed [options] [sed-commands] [input-file]
    sed [选项] [sed命令] [输入文件]

说明:
1. 注意sed和后面的选项之间至少有一个空格。
2. 为了避免混淆,本文称呼sed为sed软件。sed-commands(sed命令)是sed软件内置的一些命令选项,为了和前面的options(选项)区分,故称为sed命令。
3. sed-commands既可以是单个sed命令,也可以是多个sed命令组合。
4. input-file(输入文件)是可选项,sed还能够从标准输入如管道获取输入。


sed 定位

sed 命令在没有给定的位置时,默认会处理所有行。

 

sed 支持以下几种地址类型:

  1. first~step

    • first 指 起始匹配行
    • sed -n 2~5p
      • 从第二行开始匹配,隔5行匹配一次,即2,7,12,...
  2. $
    • 表示匹配最后一行
    • sed -n '$p' person.txt
  3. /REGEXP/

    • 表示匹配正则那一行,通过//之间的正则来匹配
  4. \cREGEXPc

    • 表示匹配正则那一行,通过\c和c之间的正则来匹配,c可以是任一字符
  5. addr1, addr2
    • 定址 addr1,addr2 决定用于对哪些行进行编辑。地址的形式可以是数字、正则表达式或二者的结合
    • 如果没有指定地址,sed 将处理输入文件中的所有行。
    • 如果定址是一个数字,则这个数字代表行号,如果是逗号分隔的两个行号,那么需要处理的定址就是两行之间的范围(包括两行在内)。范围可以是数字,正则或二者组合。
  6. addr1,+N
    • 从addr1 这行到往下 N行匹配,总共匹配N+addr1 行
  7. addr1,~N
    • 匹配从addr1开始,到找到N的倍数行结束。
    • 从第13行开始,到5的倍数行结束,这里即第15行结束:
    • sed -n "13,~5p" sed_test.txt
    • # 前面的输出为行号,后面为找到的匹配的值,符合N的倍数规则
      [root@oldboy /]# cat sed_test.txt -n|sed '/aa/,~2p' -n
      101 aa
      102 bb
      108 aa
      109 1
      110 2
      113 aa
      114 5
      117 aa
      118 AAA

指定执行的地址范围:

  • sed软件可以对单行或多行进行处理。如果在sed命令前面不指定地址范围,那么默认会匹配所有行。
  • 用法:n1[,n2]{sed-commands}
  • 地址用逗号分隔的,n1,n2可以用数字、正则表达式、或二者的组合表示。
  • 例如:

    • 10{sed-commands} 对第10行进行操作
    • 10,20{sed-commands} 对第10到20行进行操作,包括第10和20行
    • 10,+20{sed-commands} 对10到30(10+20)行操作,包括第10,30行
    • 1~2{sed-commands} 对1,3,5,7,……行操作
    • 10,${sed-commands} 对10到最后一行($代表最后一行)操作,包括第10行
    • 10,~20 对10行到20的倍数行
  • 正则匹配和其他方式的混合的方式:

    • /oldboy/{sed-commands} 对匹配oldboy的行操作
    • /oldboy/,/Alex/{sed-commands} 对匹配oldboy的行到匹配Alex的行操作
    • /oldboy/,${sed-commands} 对匹配oldboy的行到最后一行操作

    • /oldboy/,10{sed-commands} 对匹配oldboy的行到第10行操作,注意:如果前10行没有匹配到oldboy,sed软件会显示10行以后的匹配oldboy的行,如果有。

    • 1,/Alex/{sed-commands} 对第1行到匹配Alex的行操作
    • /oldboy/,+2{sed-commands} 对匹配oldboy的行到其后的2行操作10,${sed-commands} 对10到最后一行($代表最后一行)操作,包括第10行

sed的常用选项

  • -n 使用安静模式,在一般情况下所有的STDIN都会输出到屏幕上,-n选项只打印被sed 特殊处理的行
  • -e 多重编辑,且命令顺序会影响结果
  • -f 指定一个sed脚本文件到命令行执行
  • -r 可以使用扩展正则
  • -i 直接修改文档读取的内容,不在屏幕上输出

sed 操作命令

sed 操作命令告诉sed 如何处理由地址指定的各输入行。如果没有指定地址,sed就会处理输入的所有的行。

 

  • a 在当前行后 添加一行或多行 add

    • sed '5a 106,dandan,CSO' person.txt
  • i 在当前行之前插入文本 insert
    • sed '2i 106,dandan,CSO' person.txt

  • d 删除行 delete

  • c 用新行替换旧行:用新文本修改(替换)当前行中的文本 change
  • s 用一个字符串替换另一个
    • 单独使用,将每一行中第一处匹配的字符串进行替换,sed命令
    • g 每一行进行全部替换,是sed命令s的替换标志之一,非sed命令
    • 替换格式:
      • sed -i 's#old text#new text#g' filename_stdin
  • -i 修改文件内容,sed软件的选项
  • -r 可以使用扩展正则表达式
  • () \1 后向引用,分组替换,与-r结合使用,可以不使用转义符号\;
    • 最多可以用上9个分组
  • $var 可以使用变量,双引号会解析变量
  • & 代表被替换的内容

  • p 打印行,输出指定内容,但默认会输出2次匹配的结果,因此使用-n取消默认输出
  • h 把模式空间里的内容复制到暂存缓冲区
  • H 把模式空间里的内容追加到暂存缓冲区
  • g 取出暂存缓冲区里的内容,将其复制到模式空间,覆盖该处原有内容
  • G 取出暂存缓冲区里的内容,将其复制到模式空间,追加在原有内容后面
  • l 列出非打印字符

  • n 读入下一输入行,并从下一条命令而不是第一条命令开始处理

  • q 结束或退出sed
  • r 从文件中读取输入行
  • ! 对所选行意外的所有行应用命令

替换标志:

  • g 在行内进行全局替换 global
  • p 打印行
  • w 将行写入文件
  • x 交换暂存缓冲区与模式空间的内容
  • y 将字符转换为另一字符(不能对正则表达式使用y命令)

报错信息和退出信息

遇到语法错误时, sed 会向标准错误输出发送一条相当简单的报错信息。

但是,如果 sed 判断不出错在何处,它会“断章取义”,给出令人迷惑的报错信息。

如果没有语法错误, sed 将会返回给 shell 一个退出状态,状态为 0 代表成功,为非 0 整数代表失败。

 

4. 实例

统一实例文本:

[root@oldboy test]# cat person.txt
101,oldboy,CEO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CTO

增删改查

  • a 追加文本到指定行后
  • i 插入文本到指定行前

这两个参数和vi编辑器的意思是一样的,i是insert插入,a是add增加

 

单行增加

# 5a 在第五行之后添加文本
[root@oldboy test]# sed '5a 106,dandan,CSO' person.txt
101,oldboy,CEO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CTO
106,dandan,CSO # 2i 在第二行之前添加文本
[root@oldboy test]# sed '2i 106,dandan,CSO' person.txt
101,oldboy,CEO
106,dandan,CSO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CTO # 打印person.txt,发现add的文本未写入文件
[root@oldboy test]# cat person.txt
101,oldboy,CEO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CTO
多行增加:
# 第一种写法:\n换行符
[root@oldboy test]# sed '2a 106,dandan,CSO\n107,bingbing,CCO' person.txt
101,oldboy,CEO
102,zhangyao,CTO
106,dandan,CSO
107,bingbing,CCO
103,Alex,COO
104,yy,CFO
105,feixue,CTO # 第二种写法:通过"\"(回车) 多行输入
[root@oldboy test]# sed '2a 106,dandan,CSO \
> 107,bingbing.CCO' person.txt
101,oldboy,CEO
102,zhangyao,CTO
106,dandan,CSO
107,bingbing.CCO
103,Alex,COO
104,yy,CFO
105,feixue,CTO

企业案例

在我们学习系统优化时,有一个优化点:更改ssh服务远程登录的配置

主要的操作是在ssh的配置文件加入下面5行文本。(下面参数的具体含义见其他课程。)

Port 52113
PermitRootLogin no
PermitEmptyPasswords no
UseDNS no
GSSAPIAuthentication no

我们可以使用vi命令编辑这个文本,但这样就比较麻烦,现在想一条命令增加5行文本到第13行前?

sed '13i Port 52113\
PermitRootLogin no\
PermitEmptyPasswords no\
UseDNS no\
GSSAPIAuthentication no' /etc/ssh/sshd_config

  • d 删除行 delete
# 删除所有行
[root@oldboy test]# sed 'd' person.txt # 删除第2行
[root@oldboy test]# sed '2d' person.txt
101,oldboy,CEO
103,Alex,COO
104,yy,CFO
105,feixue,CTO # 删除第2到第5行
[root@oldboy test]# sed '2,5d' person.txt
101,oldboy,CEO # 删除第三行到最后一行
[root@oldboy test]# sed '3,$d' person.txt
101,oldboy,CEO
102,zhangyao,CTO # 删除1,3,5行,剩余2,4行
[root@oldboy test]# sed '1~2d' person.txt
102,zhangyao,CTO
104,yy,CFO # 删除1-3行,剩余4,5行
[root@oldboy test]# sed '1,+2d' person.txt
104,yy,CFO
105,feixue,CTO # 删除匹配到zhangyao的行
[root@oldboy test]# sed '/zhangyao/d' person.txt
101,oldboy,CEO
103,Alex,COO
104,yy,CFO
105,feixue,CTO # 删除匹配到oldboy的行到匹配到Alex的行
[root@oldboy test]# sed '/oldboy/,/Alex/d' person.txt
104,yy,CFO
105,feixue,CTO # 删除从匹配到oldboy的行到第三行,剩余4,5行
[root@oldboy test]# sed '/oldboy/,3d' person.txt
104,yy,CFO
105,feixue,CTO

特殊情况:正则匹配的行不在后面的行的范围限制内,直接匹配到第五行,并删除第五行,第2行保留。
原因:正则范围内的行首,没匹配到还会继续匹配下去

[root@oldboy test]# cat person.txt
101,oldboy,CEO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CTO
[root@oldboy test]# sed '/feixue/,2d' person.txt
101,oldboy,CEO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO

企业案例:打印文件内容但不包含oldboy

[root@oldboy test]# sed '/oldboy/d' person.txt
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CTO

  • c 用新文本修改(替换)当前行中的文本 change
 

按行替换

# 将第二行内容修改
[root@oldboy test]# sed '2c 106,dandan,CSO' person.txt
101,oldboy,CEO
106,dandan,CSO
103,Alex,COO
104,yy,CFO
105,feixue,CTO # 不指定行号,则会修改全部行
[root@oldboy test]# sed 'c 106,dandan,CSO' person.txt
106,dandan,CSO
106,dandan,CSO
106,dandan,CSO
106,dandan,CSO
106,dandan,CSO

文本替换

  • s:单独使用→将每一行中第一处匹配的字符串进行替换 ==>sed命令
  • g:每一行进行全部替换 ==>sed命令s的替换标志之一,非sed命令
  • -i:修改文件内容 ==>sed软件的选项
sed软件替换模型(方框▇被替换成三角▲)

sed -i 's/▇/▲/g' oldboy.log
sed -i 's#▇#▲#g' oldboy.log

观察特点:

  1. 两边是引号,引号里面的两边分别为s和g,中间是三个一样的字符"/" 或 "#" 作为定界符。"#"能在替换内容包含"/" 有助于区别。定界符可以是任意符号如":"或"|"等,但当替换内容包含定界符时,需转义即":" "|"。经过长期实践,建议大家使用"#"作为定界符。
  2. 定界符"/" 或 "#",第一个和第二个之间的就是被替换的内容,第二个和第三个之间的就是替换后的内容。
  3. s#▇#▲#g,▇能用正则表达式,但▲不能用,必须是具体的。
  4. 默认sed软件是对模式空间(内存中的数据)操作,而-i选项会更改磁盘上的文件内容。
#### [root@oldboy test]# cat person.txt
101,oldboy,CEO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CTO # 将zhangyao替换为oldboyedu
[root@oldboy test]# sed 's#zhangyao#oldboyedu#g' person.txt
101,oldboy,CEO
102,oldboyedu,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CTO

企业案例:指定行修改配置文件,防止修改多处

[root@oldboy test]# sed '3s#0#9#g' person.txt
101,oldboy,CEO
102,zhangyao,CTO
193,Alex,COO
104,yy,CFO
105,feixue,CTO

变量替换

# 创建一个新的测试文本
[root@oldboy test]# cat test.txt
a
b
a # 定义变量x,y
[root@oldboy test]# x=a
[root@oldboy test]# y=b # 查看变量x,y
[root@oldboy test]# echo $x $y
a b # 将变量x替换成变量y,也就是a替换成b
[root@oldboy test]# sed "s#$x#$y#g" test.txt
b
b
b
[root@oldboy test]# sed s#$x#$y#g test.txt
b
b
b

单引号,所见即所得,不会将变量进行;
双引号,变量置换功能,解析变量后输出,不加引号相当于双引号。

[root@oldboy test]# sed 's#$x#$y#g' test.txt
a
b
a

用eval解析:

[root@oldboy test]# eval sed 's#$x#$y#g' test.txt
b
b
b
's#'$x'#'$y'#g'是  's#'  $x  '#'  $y  '#g' 字符串和变量的拼接:
[root@oldboy test]# sed 's#'$x'#'$y'#g' test.txt
b
b
b

分组替换

( )和\1的使用说明(后向引用):

sed软件的 () 的功能可以记住正则表达式的一部分,其中,\1为第一个记住的模式即第一个小括号中的匹配内容,\2第二记住的模式,即第二个小括号中的匹配内容,sed最多可以记住9个。

 

例:echo I am oldboy teacher.如果想保留这一行的单词oldboy,删除剩下的部分,使用圆括号标记想保留的部分。

[root@oldboy test]# echo I am oldboy teacher.|sed -r 's#^.*(oldboy).*$#\1#g'
oldboy [root@oldboy test]# echo I am oldboy teacher.|sed -r 's#^.*am (.*) tea.*$#\1#g'
oldboy

注意:

  1. 如果没有使用-r参数,就要使用转移符号\将()转义;使用-r参数,表示可以使用扩展正则表达式
  2. ()\1 \2 这种是 后向引用的方式。
 

企业案例:系统开机启动项优化

[root@oldboy test]# chkconfig --list|grep '3:on'|grep -vE "sshd|crond|network|rsyslog|sysstat"|awk '{print $1}'|sed -r 's#^(.*)#chkconfig \1 off#g'|bash

特殊符号& 代表被替换的内容

# 将第1到第3行中的C替换为"--C--",此处:&代表C

[root@oldboy test]# sed '1,3s#C#--&--#g' person.txt
101,oldboy,--C--EO
102,zhangyao,--C--TO
103,Alex,--C--OO
104,yy,CFO
105,feixue,CTO

企业案例:批量重命名文件

[root@oldboy test]# touch stu_10299_{1..5}_finished.jpg
[root@oldboy test]# ls
person.txt stu_10299_2_finished.jpg stu_10299_4_finished.jpg test.txt
stu_10299_1_finished.jpg stu_10299_3_finished.jpg stu_10299_5_finished.jpg # 要求用sed命令重命名,效果为stu_102999_1_finished.jpg==>stu_102999_1.jpg,即删除文件名的_finished [root@oldboy test]# ls *.jpg|sed 's#(^.*)_finished(.*)$#mv & \1\2#g' -r
mv stu_10299_1_finished.jpg stu_10299_1.jpg
mv stu_10299_2_finished.jpg stu_10299_2.jpg
mv stu_10299_3_finished.jpg stu_10299_3.jpg
mv stu_10299_4_finished.jpg stu_10299_4.jpg
mv stu_10299_5_finished.jpg stu_10299_5.jpg [root@oldboy test]# ls *.jpg|sed 's#(^.*)_finished(.*)$#mv & \1\2#g' -r|bash [root@oldboy test]# ls *.jpg
stu_10299_1.jpg stu_10299_2.jpg stu_10299_3.jpg stu_10299_4.jpg stu_10299_5.jpg

  • p 打印行,输出指定内容,但默认会输出2次匹配的结果,因此使用-n取消默认输出
 

查询:

# p参数会默认输出两次,要使用-n参数取消默认输出
[root@oldboy test]# sed '2p' person.txt
101,oldboy,CEO
102,zhangyao,CTO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CTO [root@oldboy test]# sed '2p' person.txt -n
102,zhangyao,CTO # 输出第2到第3行
[root@oldboy test]# sed '2,3p' person.txt -n
102,zhangyao,CTO
103,Alex,COO # 输出1,3,5行
[root@oldboy test]# sed '1~2p' person.txt -n
101,oldboy,CEO
103,Alex,COO
105,feixue,CTO # 输出所有行
[root@oldboy test]# sed 'p' person.txt -n
101,oldboy,CEO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CTO

字符串查询:

[root@oldboy test]# sed -n '/CTO/p' person.txt
102,zhangyao,CTO
105,feixue,CTO
[root@oldboy test]# sed -n '/CTO/,/CFO/p' person.txt
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CTO

混合查询:

[root@oldboy test]# sed -n '/CTO/p' person.txt
102,zhangyao,CTO
105,feixue,CTO
[root@oldboy test]# sed -n '/CTO/,/CFO/p' person.txt
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CTO
 

【三剑客】sed命令的更多相关文章

  1. 文本处理三剑客之sed命令

    第十八章.文本处理三剑客之sed命令 目录 sed介绍 sed命令常用选项 sed常用编辑命令 sed使用示例 sed高级语法 18.1.sed简介 sed全名stream editor,流编辑器,s ...

  2. Linux实战教学笔记12:linux三剑客之sed命令精讲

    第十二节 linux三剑客之sed命令精讲 标签(空格分隔): Linux实战教学笔记-陈思齐 ---更多资料点我查看 1,前言 我们都知道,在Linux中一切皆文件,比如配置文件,日志文件,启动文件 ...

  3. day14 linux三剑客之sed命令

    day14 linux三剑客之sed命令 sed命令 Sed 主要用来自动编辑一个或多个文件.简化对文件的反复操作.编写转换程序等. sed(流式编辑器) : sed主要用来修改文件. 1.sed命令 ...

  4. linux三剑客之sed命令

    一.前言 我们都知道,在Linux中一切皆文件,比如配置文件,日志文件,启动文件等等.如果我们相对这些文件进行一些编辑查询等操作时,我们可能会想到一些vi,vim,cat,more等命令.但是这些命令 ...

  5. Shell三剑客之sed命令

    Sed简介 Sed是Stream Editor(流编辑器)缩写,是操作.过滤和转换文本内容的强大工具,常用功能有增删改查. Sed命令执行流程 Sed语法格式 Sed [option] ‘[匹配][处 ...

  6. Linux三剑客之老二-------sed命令详解

    sed命令 文件 编辑 本文索引 [隐藏] sed的选项.命令.替换标记 选项 参数 sed命令 sed替换标记 sed元字符集 sed用法实例 替换操作:s命令 全面替换标记g 定界符 删除操作:d ...

  7. shell 三剑客之 sed 命令详解

    sed 编辑命令 sed 编辑命令对照表 把 /etc/passwd 文件赋值到当前路径下,进行操作 cp /etc/passwd ./ cat -n passwd sed 删除操作 删除 passw ...

  8. Linux sed命令 -- 三剑客老二

    格式: sed [OPTION]... {script-only-if-no-other-script} [input-file]... sed [OPTION]... ‘地址定界+[高级]编辑命令’ ...

  9. <三剑客> 老二:sed命令用法

    sed命令的用法: sed是一种流编辑器,它是文本处理中非常中的工具,能够完美的配合正则表达式使用,功能不同凡响.处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space ...

随机推荐

  1. pinpoint配置使用

    一.下载pinpoint包 从https://github.com/naver/pinpoint/releases 下载 pinpoint-agent.tar.gz pinpoint-collecto ...

  2. Linux基础:Day04

    进程管理1.操作系统基础 调用:kernel通过给应用程序提供system call方式来提供硬件资源:  注意:这个应用程序也包括库文件:  库文件是运行在ring 0上的一段程序代码,不对客户直接 ...

  3. spring03

    学习了spring的数据源的使用以及spring的作用域引入外部属性文件 对应的bean的xml文件和properties文件如下 <?xml version="1.0" e ...

  4. 大数据及hadoop简要概念

    大数据 大数据简要概念 指无法在一定时间范围内用常规软件工具进行捕捉.管理和处理的数据集合.需要新处理模式,才能具有更强的决策力.洞察发现力和流程优化能力的海量.高增长率和多样化的信息资产. 大数据作 ...

  5. Levenshtein算法-比较两个字符串之间的相似度

    package com.sinoup.util;/** * Created by Administrator on 2020-4-18. */ /** * @Title: * @ProjectName ...

  6. Netty 中的异步编程 Future 和 Promise

    Netty 中大量 I/O 操作都是异步执行,本篇博文来聊聊 Netty 中的异步编程. Java Future 提供的异步模型 JDK 5 引入了 Future 模式.Future 接口是 Java ...

  7. C - Roads in the North DFS+树的直径

    Building and maintaining roads among communities in the far North is an expensive business. With thi ...

  8. 数据挖掘入门系列教程(九)之基于sklearn的SVM使用

    目录 介绍 基于SVM对MINIST数据集进行分类 使用SVM SVM分析垃圾邮件 加载数据集 分词 构建词云 构建数据集 进行训练 交叉验证 炼丹术 总结 参考 介绍 在上一篇博客:数据挖掘入门系列 ...

  9. 深入浅出node.js游戏服务器开发1——基础架构与框架介绍

    2013年04月19日 14:09:37 MJiao 阅读数:4614   深入浅出node.js游戏服务器开发1——基础架构与框架介绍   游戏服务器概述 没开发过游戏的人会觉得游戏服务器是很神秘的 ...

  10. Linux 平台 安装 Composer

    1.检查是否安装 composer --version 2.下载安装 php -r "copy('https://install.phpcomposer.com/installer', 'c ...