sed小结

sed

http://blog.oldboyedu.com/commands-sed/

http://coolshell.cn/articles/9104.html

http://www.gnu.org/software/sed/manual/sed.html

http://sed.sourceforge.net/sed1line_zh-CN.html

功能概括

增删改查,过滤,取行

执行的流程

Sed软件从文件或管道中读取一行,处理一行,输出一行;再读取一行,再处理一行,再输出一行……
模式空间:sed软件内部的一个临时缓存,用于存放读取到的内容。

sed.jpg

示例1

# 示例文本
cat /etc/person.txt
101,oldboy,CEO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO

$ cat test.txt
a
b
a

增:a追加与i插入

# 单行
sed '2a 106,dandan,CSO' person.txt
sed '2i 106,dandan,CSO' person.txt

# 多行
sed '2a 106,dandan,CSO\n107,bingbing,CCO' person.txt
# 一行结束,命令未输完可以用\(反斜线)

指定执行的地址范围

用法: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行
/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行操作

删:d

# 全部删除
sed 'd' person.txt
sed '2d' person.txt
sed '2,5d' person.txt
sed '3,$d' person.txt
sed '1~2d' person.txt
sed  '1,+2d' person.txt
sed '/zhangyao/d' person.txt
sed '/oldboy/,/Alex/d' person.txt
sed '/oldboy/,3d' person.txt

改:c/s

c:按行替换,新行替换旧行
s:文本替换

s:单独使用→将每一行中第一处匹配的字符串进行替换 ==>sed命令
g:每一行进行全部替换 ==>sed命令s的替换标志之一,非sed命令
-i:修改文件内容 ==>sed软件的选项

sed '2c 106,dandan,CSO' person.txt

sed软件替换模型(方框▇被替换成三角▲)

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

观察特点

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

变量替换

$ x=a
$ y=b
$ echo $x $y
a b
$ sed s#$x#$y#g test.txt
b
b
b
$ sed 's#$x#$y#g' test.txt
a
b
a
$ sed 's#'$x'#'$y'#g' test.txt
b
b
b
$ sed "s#$x#$y#g" test.txt
b
b
b
$ eval sed 's#$x#$y#g' test.txt
b
b
b

分组替换

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

# echo I am oldboy teacher.如果想保留这一行的单词oldboy,删除剩下的部分,使用圆括号标记想保留的部分。
[root@oldboy ~]# echo I am oldboy teacher. |sed 's#^.*am \([a-z].*\) tea.*$#\1#g'
oldboy
[root@oldboy ~]# echo I am oldboy teacher. |sed -r 's#^.*am ([a-z].*) tea.*$#\1#g'
oldboy
[root@oldboy ~]# echo I am oldboy teacher. |sed -r 's#I (.*) (.*) teacher.#\1\2#g'
amoldboy

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

sed '1,3s#C#--&--#g' person.txt #→此处&等于C

查:p

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

# 按行查询(取行用sed最简单)
sed '2p' person.txt
sed -n '2p' person.txt
sed -n '2,3p' person.txt
sed -n '1~2p' person.txt
sed -n 'p' person.txt

# 按字符查询
sed -n '/CTO/p' person.txt
sed -n '/CTO/,/CFO/p' person.txt

# 混合查询
sed -n '2,/CFO/p' person.txt
sed -n '/feixue/,2p' person.txt
# 特殊情况,前两行没有匹配到feixue,就向后匹配,如果匹配到feixue就打印此行。

案例

案例1:修改sshd配置文件

/etc/ssh/sshd_config
Port 52113
PermitRootLogin no
PermitEmptyPasswords no
UseDNS no
GSSAPIAuthentication no

cp /etc/ssh/sshd_config .
sed -i '$i Port 52113\nPermitRootLogin no\nPermitEmptyPasswords no\nUseDNS no\nGSSAPIAuthentication no' sshd_config

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

sed '/oldboy/d' person.txt

案例3:指定行修改配置文件

# 指定行精确修改配置文件,这样可以防止修改多了地方。
sed '3s#0#9#' person.txt

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

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

案例5:批量重命名文件

stu_102999_1_finished.jpg 
stu_102999_2_finished.jpg 
stu_102999_3_finished.jpg 
stu_102999_4_finished.jpg 
stu_102999_5_finished.jpg

# 重命名效果
stu_102999_1_finished.jpg==>stu_102999_1.jpg

find ~ -type f -name "*.jpg" | sed -r 's/(^.*)_finished(\.jpg)/mv & \1\2/g' | bash

实例2

# 示例文件
$ cat pets.txt
This is my cat
  my cat's name is betty
This is my dog
  my dog's name is frank
This is my fish
  my fish's name is george
This is my goat
  my goat's name is adam

$ cat html.txt
html.txt: <b>This</b> is what <span style="text-decoration: underline;">I</span> meant. Understand?

$ cat my.txt
This is my cat, my cat's name is betty
This is my dog, my dog's name is frank
This is my fish, my fish's name is george
This is my goat, my goat's name is adam

$ cat t.txt
one
two
three

s命令:替换

# 把其中的my字符串替换成Hao Chen’s
sed "s/my/Hao Chen's/g" pets.txt

# 把结果写到文件
sed "s/my/Hao Chen's/g" pets.txt > hao_pets.txt

# 直接修改文件内容
sed -i "s/my/Hao Chen's/g" pets.txt

# 在每一行最前面加点东西
sed 's/^/#/g' pets.txt

# 在每一行最后面加点东西
sed 's/$/ --- /g' pets.txt

# 替换html中的标签
sed 's/<[^>]*>//g' html.txt

# 只替换第3到第6行的文本
sed '3,6s/my/your/g' pets.txt

# 只替换每一行的第一个s
sed 's/s/S/' my.txt

# 只替换每一行的第二个s
sed 's/s/S/g2' my.txt

# 只替换第一行的第3个以后的s
sed 's/s/S/g3' my.txt

# 第一个模式把第一行到第三行的my替换成your,第二个则把第3行以后的This替换成了That
sed '1,3s/my/your/g; 3,$s/This/That/g' my.txt
sed -e '1,3s/my/your/g' -e '3,$s/This/That/g' my.txt

# 对匹配的单词两边加[]
sed 's/my/[&]/g' my.txt

# 使用圆括号匹配的示例:(圆括号括起来的正则表达式所匹配的字符串会可以当成变量来使用,sed中使用的是\1,\2…)
# my.txt中,输出 动物:名字
sed 's/This is my \([^,]*\),.*is \(.*\)/\1:\2/g' my.txt
正则为:This is my ([^,]*),.*is (.*)
匹配为:This is my (cat),……….is (betty)
然后:\1就是cat,\2就是betty

# 使用扩展正则表达式
sed -r 's/This is my ([^,]*),.*is (.*)/\1:\2/g' my.txt

# 关于address可以使用相对位置
# 其中的+3表示后面连续3行
sed '/dog/,+3s/^/# /g' pets.txt

N命令

把下一行的内容纳入当成缓冲区做匹配

# 把原文本中的偶数行纳入奇数行匹配,而s只匹配并替换一次(把两行合并成一行,再进行匹配)
sed 'N;s/my/your/' pets.txt

sed 'N;s/\n/,/' pets.txt

a命令和i命令

a命令就是append, i命令就是insert,它们是用来添加行的

# 其中的1i表明,其要在第1行前插入一行(insert)
sed "1 i This is my monkey, my monkey's name is wukong" my.txt

# 其中的1a表明,其要在最后一行后追加一行(append)
sed "$ a This is my monkey, my monkey's name is wukong" my.txt

c命令

替换匹配行

sed "2 c This is my monkey, my monkey's name is wukong" my.txt
sed "2s/^.*$/This is my monkey, my monkey's name is wukong/g" my.txt

sed "/fish/c This is my monkey, my monkey's name is wukong" my.txt

d命令

删除匹配行

sed '/fish/d' my.txt
sed '2d' my.txt
sed '2,$d' my.txt

p命令

打印命令 你可以把这个命令当成grep式的命令

# 匹配fish并输出,可以看到fish的那一行被打了两遍,
# 这是因为sed处理时会把处理的信息输出
sed '/fish/p' my.txt

# 使用n参数就好了
sed -n '/fish/p' my.txt

# 从一个模式到另一个模式
sed -n '/dog/,/fish/p' my.txt

#从第一行打印到匹配fish成功的那一行
sed -n '1,/fish/p' my.txt

命令打包

cmd可以是多个,它们可以用分号分开,可以用大括号括起来作为嵌套命令

# 对3行到第6行,执行命令/This/d
sed '3,6 {/This/d}' pets.txt

# 对3行到第6行,匹配/This/成功后,再匹配/fish/,成功后执行d命令
sed '3,6 {/This/{/fish/d}}' pets.txt

# 从第一行到最后一行,如果匹配到This,则删除之;如果前面有空格,则去除空格
sed '1,${/This/d;s/^ *//g}' pets.txt

Hold Space

第三个我们再来看一下 Hold Space
接下来,我们需要了解一下Hold Space的概念,我们先来看四个命令:
g: 将hold space中的内容拷贝到pattern space中,原来pattern space里的内容清除
G: 将hold space中的内容append到pattern space\n后
h: 将pattern space中的内容拷贝到hold space中,原来的hold space里的内容被清除
H: 将pattern space中的内容append到hold space\n后
x: 交换pattern space和hold space的内容

hold space只是在两次处理cycles间临时可以用于保存内容的buffer,必要时以避免pattern space第一次处理后的结果被第二次读取覆盖

# demo1
sed 'H;g' t.txt
sed_demo_00.jpg
# 反序了一个文件的行
sed '1!G;h;$!d' t.txt

# 1!G —— 只有第一行不执行G命令,将hold space中的内容append回到pattern space
# h —— 第一行都执行h命令,将pattern space中的内容拷贝到hold space中
# $!d —— 除了最后一行不执行d命令,其它行都执行d命令,删除当前行
sed_demo.jpg
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,616评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,020评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,078评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,040评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,154评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,265评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,298评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,072评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,491评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,795评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,970评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,654评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,272评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,985评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,815评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,852评论 2 351

推荐阅读更多精彩内容

  • Sed工具工作原理及特性 1. sed是流编辑器,每一次读取一行到内存中,即称之为模式空间(pattern spa...
    魏镇坪阅读 10,941评论 0 12
  • 本文承接之前写的三十分钟学会AWK一文,在学习完AWK之后,趁热打铁又学习了一下SED,不得不说这两个工具真的堪称...
    mylxsw阅读 4,393评论 3 74
  • linux资料总章2.1 1.0写的不好抱歉 但是2.0已经改了很多 但是错误还是无法避免 以后资料会慢慢更新 大...
    数据革命阅读 12,151评论 2 33
  • sed与awk实例 文本间隔 在每一行后面增加一空行 将原来的所有空行删除并在每一行后面增加一空行。这样在输出的文...
    stuha阅读 1,893评论 0 21
  • sed篇总共分成6章:(简书版) Sed&awk笔记之sed篇:简单介绍 Sed&awk笔记之sed篇:模式空间与...
    magic5650阅读 630评论 0 3