Linux三剑客(sed)-编辑匹配到的文本

sed:Stream Editor文本,sed是一个非交互式的面向字符流的编辑器。能同时处理多个文件多行的内容。

sed编辑器是一行一行的处理文件,正在处理的内容存放在模式空间(缓冲区)中,处理完毕后按照选项的规定进行输出或文件的修改。

sed主要用来自动编辑一个或多个文件;简化文件的反复操作,用于非交互编译文件。

1. 语法

sed [options] '[command]' [filename]

1. sed命令的选项(option)

选项 作用
-n 只打印模式匹配的行
-e 直接在命令行模式上进行sed动作编辑,此为默认选项
-f 将sed的动作写在一个文件内
-r 支持扩展表达式
-i 直接修改文件内容

2. sed命令的命令(command)

命令 作用
p 打印匹配行(和-n选项一起使用)
= 显示文件行的行号
a 在定位行号后附加新文本信息
i 在定位行号后插入新文件信息
d 删除定位行
c 用新文本替换文本
w filename 写文本到一个文件,类似输出重定向
r filename 从另一个文件中读文件,类似输出重定向
s 使用替换模式替换相应模式
q 第一个模式匹配完成后退出或立即退出
I 显示与八进制ACSII代码等价的控制符
{} 在定位行执行的命令组,用;隔开
g 将模式2粘贴到/pattern n/

2. 实战

2.1 sed在文件中查询文本方式

1. 使用行号打印特定行

可以使用一个简单的数字,或是一个行号范围

注意:p的动作是:打印匹配行。

格式 说明
xp x为行号
x,yp 表示行号从x到y
/pattern/p 查询包含模式的行
/pattern /pattern/p 查询包含两个模式的行
/pattern/,xp 包含模式和指定行号之间的行
x,/pattern/p 通过行号和模式查询匹配的行
x,y! 查询不包含指定行号x和y的行

1. 原始文件:

[newsettle@localhost userbin]$ cat exam.log 
#/bin/sh 

第三行111
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES

2. sed的默认动作
(1)sed的默认动作是打印文件中的所有行。

[newsettle@localhost userbin]$ sed '' exam.log 
#/bin/sh 

第三行111
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES

3. 打印特定行
(1)因为sed命令默认打印文件中所有行。所以第三行会被打印两遍。那如何只打印第三行呢?使用【-n】命令,只打印匹配的行。

[newsettle@localhost userbin]$ sed '3p' exam.log 
#/bin/sh 

第三行111
第三行111
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES

(2)使用【-n】命令,只打印匹配到的行

[newsettle@localhost userbin]$ sed -n '3p' exam.log 
第三行111

(3)打印[n,m]行

[newsettle@localhost userbin]$ sed -n '3,4p' exam.log 
第三行111
第四行222

(4)打印包含模式的行

[newsettle@localhost userbin]$ sed -n '/八/p' exam.log 
END 第八行END

(5)打印包含模式和指定行号之间的行

[newsettle@localhost userbin]$ sed -n '/四/,6p' exam.log 
第四行222
第五行333
第六行444
[newsettle@localhost userbin]$ sed -n '1,/四/p' exam.log 
#/bin/sh 

第三行111
第四行222

(6)包含模式和包含模式之间的行

[newsettle@localhost userbin]$ sed -n '/三/,/四/p' exam.log 
第三行111
第四行222

(7){}执行多个命令(command),使用;隔开。=是显示文件行的行号。p是打印匹配行

[newsettle@localhost userbin]$ sed -n '1,4{=;p}' exam.log 
1
#/bin/sh 
2

3
第三行111
4
第四行222

(8)!取反操作

[newsettle@localhost userbin]$ sed -n '1,4!{=;p}' exam.log 
5
第五行333
6
第六行444
7
第七行555
8
END 第八行END
9
END 第就行END
10
第十行 3.1
11
第十一行 YES--我是真的YES 不你不YES

(9)q命令:第一个模式匹配完成后退出或立即退出,使用该命令打印前5行

[newsettle@localhost userbin]$ sed '5q' exam.log 
#/bin/sh 

第三行111
第四行222
第五行333

2. 使用正则表达式匹配行

模式 说明
^ 锚点行首的符合条件的内容,用法格式"^pattern"
$ 锚点行尾的符合条件的内容,用法格式"pattern$"
^$ 空白行
. 匹配单个字符
* 匹配紧挨着前面字符的0次或多次
.* 匹配任意长度的任意字符
? 匹配紧挨在前面字符0次或1次
{m,n} 匹配紧挨前面字符至少m次,至多n次
{m,} 匹配紧挨前面字符至少m次
<pattern> 匹配特定单词
[] 匹配指定范围内的任意单个字符
[^] 匹配指定范围外的任意单个字符
[:digit:] 所有数字;相当于0-9,[0-9]-->[[:digit:]]
[:lower:] 所有的小写字母
[:upper:] 所有的大写字母
[:alpha:] 所有的字母
[:alnum:] 相当于0-9a-zA-Z
[:space:] 空白字符
[:punct:] 所有标点符号

(1)使用[]进行正则匹配

[newsettle@localhost userbin]$ sed -n '/[[:digit:]]/p' exam.log 
第三行111
第四行222
第五行333
第六行444
第七行555
第十行 3.1
[newsettle@localhost userbin]$ sed -n '/[1-3]/p' exam.log 
第三行111
第四行222
第五行333
第十行 3.1

(2)其他的正则表达式

sed-n '/r*t/p'/etc/passwd#打印匹配r有0个或者多个,后接一个t字符的行  
sed-n '/.r.*/p'/etc/passwd#打印匹配有r的行并且r后面跟任意字符  
sed-n '/o*/p'/etc/passwd#打印o字符重复任意次  
sed-n '/o\{1,\}/p'/etc/passwd#打印o字重复出现一次以上  
sed-n '/o\{1,3\}/p'/etc/passwd#打印o字重复出现一次到三次之间以上  

2.2 对文件的操作

对文件的操作无非就是“增改删查”,sed命令怎样实现对文件的操作呢?

1. 文件的查询

(1)打印出以#开头的行,然后用!进行反选,则表示过滤掉以#开头的行,不会过滤掉空格。

[newsettle@localhost userbin]$ sed -n '/^#/!p' exam.log 

第三行111
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES

(2)匹配以#开头的行,进行取反,则打印出非#开头的行,然后其结果在对空格开头的行进行取反。即过滤掉以#开头的行和以空格开头的行。{}表示在定位行执行的命令组。

[newsettle@localhost userbin]$ sed -n '/^#/!{/^$/!p}' exam.log 
第三行111
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES

(3)sed支持对单个文件实现不同的操作,每个操作用-e参数。定位到执行的行后,使用d命令,直接删除匹配到的行。

[newsettle@localhost userbin]$ sed -e '/^#/d' -e '/^$/d' exam.log 
第三行111
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES

2. 文件的添加

需要注意的是,对源文件的添加要使用【-i】参数。

s:使用替换模式替换相应模式

(1)在匹配行前面替换字符,使用【s】命令。

[newsettle@localhost userbin]$ sed '/六/s/^/我是 /' exam.log 
#/bin/sh 

第三行111
第四行222
第五行333
我是 第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES

(2)在所有行开头替换元素【s】

[newsettle@localhost userbin]$ sed 's/^/Start /' exam.log 
Start #/bin/sh 
Start 
Start 第三行111
Start 第四行222
Start 第五行333
Start 第六行444
Start 第七行555
Start END 第八行END
Start END 第就行END
Start 第十行 3.1
Start 第十一行 YES--我是真的YES 不你不YES

(3)在所有行的末尾替换元素

[newsettle@localhost userbin]$ sed 's/$/ END/' exam.log 
#/bin/sh  END
 END
第三行111 END
第四行222 END
第五行333 END
第六行444 END
第七行555 END
END 第八行END END
END 第就行END END
第十行 3.1 END
第十一行 YES--我是真的YES 不你不YES END

(4)指定行,进行替换操作

[newsettle@localhost userbin]$ sed '3,4s/^/#/' exam.log 
#/bin/sh 

#第三行111
#第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES

(5)【&】符号代表的是匹配到的字符。在匹配到字符后,可以使用&代替。

[newsettle@localhost userbin]$ sed 's/第三行/你猜 &/' exam.log 
#/bin/sh 

你猜 第三行111
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES
[newsettle@localhost userbin]$ sed 's/第三行/& 你猜 /' exam.log 
#/bin/sh 

第三行 你猜 111
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES

(6)在匹配到行前面添加一行,使用【i】的命令

[newsettle@localhost userbin]$ sed '/第四行/i 你好' exam.log 
#/bin/sh 

第三行111
你好
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES
[newsettle@localhost userbin]$ sed '/第四行/i \你好' exam.log 
#/bin/sh 

第三行111
你好
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES

(7)在匹配行的后面添加一行,使用【a】命令

[newsettle@localhost userbin]$ sed '/第四行/a 你好' exam.log 
#/bin/sh 

第三行111
第四行222
你好
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES

(8)当添加多行时,使用\n来转义

[newsettle@localhost userbin]$ sed '/第四行/a 你好\n世界' exam.log 
#/bin/sh 

第三行111
第四行222
你好
世界
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES

(9)@代表的是【地址定界符】,一般由三个组成,定界符可以是/,$,#等特殊字符,此命令表示,匹配特定字符的行进行替换。

[newsettle@localhost userbin]$ sed '/第三行/s@111@222@' exam.log 
#/bin/sh 

第三行222
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES

需要注意的是:替换默认是修改匹配行中第一次出现的字符。

[newsettle@localhost userbin]$ sed '/YES/s@YES@NO@' exam.log 
#/bin/sh 

第三行111
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 NO--我是真的YES 不你不YES

(10)使用命令【g】修改全文中出现的匹配字符。

[newsettle@localhost userbin]$ sed '/YES/s@YES@NO@g' exam.log 
#/bin/sh 

第三行111
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 NO--我是真的NO 不你不NO

(11)若后面接数字之后在接g,表示匹配的行中,第几次出现。就替换,2g表示替换行中第二次出现。

[newsettle@localhost userbin]$ sed '/YES/s@YES@NO@2g' exam.log 
#/bin/sh 

第三行111
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的NO 不你不NO

3. 文件行的删除

(1)删除以非#号开头的行,即显示以#号开头的行。

[newsettle@localhost userbin]$ sed '/^#/!d' exam.log 
#/bin/sh 

(2)删除第一行

[newsettle@localhost userbin]$ sed '1d' exam.log 

第三行111
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES

(3)删除最后一行

[newsettle@localhost userbin]$ sed '$d' exam.log 
#/bin/sh 

第三行111
第四行222
第五行333
第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1

(4)删除指定的行区间

[newsettle@localhost userbin]$ sed '3,5d' exam.log 
#/bin/sh 

第六行444
第七行555
END 第八行END
END 第就行END
第十行 3.1
第十一行 YES--我是真的YES 不你不YES

(5)删除包含特定单词的行

[newsettle@localhost userbin]$ sed '/\<END\>/d' exam.log 
#/bin/sh 

第三行111
第四行222
第五行333
第六行444
第七行555
第十行 3.1
第十一行 YES--我是真的YES 不你不YES

本文参考:
sed命令详解

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

推荐阅读更多精彩内容

  • grep擅长查找,awk擅长分析(select),sed擅长批量编辑行 概述 SED的英文全称是 Stream E...
    piziyang12138阅读 934评论 0 3
  • grep擅长查找,awk擅长分析(select),sed擅长批量编辑行概述SED的英文全称是 Stream EDi...
    Arroganter阅读 1,067评论 0 7
  • 一、前言 我们都知道,在Linux中一切皆文件,比如配置文件,日志文件,启动文件等等。如果我们相对这些文件进行一些...
    以七v为书阅读 1,509评论 0 5
  • 简介 sed 是一种在线编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(p...
    699b979fc4da阅读 993评论 0 1
  • 噢我为啥要学python 我也不懂 我vue还没学清楚啊 (ノ`Д)ノ算了学吧主要参考:廖雪峰的python教程h...
    杨肆月阅读 172评论 0 0