shell脚本学习7-sed编辑器

    除了使用vi或者vim来编辑文本,还可以使用sed和awk命令编辑器批量处理 文本,本节学习sed编辑器。sed是流编辑器(stream editor),根据预先定好的规则处理文本。sed一次取出一行进行处理,并把结果输出到标准输出中。
  1. sed的输入

1.1 用管道给sed输入要处理上的数据
用管道给sed输入数据,举例如下:

echo "wu lin wai zhuan"|sed 's/wai/nei/'

运行后结果为:

wu lin nei zhuan

这里的s是替换(substitute)的意思。

1.2 sed命令从文本文件中一行行取数据去处理
建立testfile文件,文件内容如下:

wu lin wai zhuan is good.
da ran fang is good.
xi you ji hou zhuan is good.

然后用sed命令把所有的good改成wonderful,输入:

sed 's/good/wonderful/' testfile

结果为:

wu lin wai zhuan is wonderful.
da ran fang is wonderful.
xi you ji hou zhuan is wonderful.

注意,sed命令并不会修改testfile内容,而是把结果输出到标准输出中。

1.3 使用多个指令
在使用sed命令的时候使用多个指令的时候要用-e选项。比如想把上面的testfile中的is改成was,把good改成great。
输入:

sed -e 's/is/was/;s/good/great/' testfile

输出结果为:

wu lin wai zhuan was great.
da ran fang was great.
xi you ji hou zhuan was great.

注意命令与命令之间使用分好隔开。
1.4 把指令放到文件中
有时候可以把较多的指令放进一个文件中,然后用sed命令去加载。建立一个文件去存储命令,建立文件sedfile,内容如下:

s/is/was/
s/good/great/

然后在sed命令后面增加-f参数去加载这个文件。

sed -f sedfile testfile

运行结果为:

wu lin wai zhuan was great.
da ran fang was great.
xi you ji hou zhuan was great.
  1. 介绍更多sed命令
    2.1 字符串替换
    字符串替换的模式为:
    s/pattern/dest_string/flag
    pattern是要匹配的字符串,dest_string是替换后的字符串,flag有4种情况。
    默认情况下,flag为空,这个时候就把该行中匹配的第一个字符串替换。
    比如建立一个文件如下:
liao ning wei shi, hu nan wei shi
jiang xi wei shi, zhe jiang wei shi
jiang su wei shi, ning xia wei shi,

1) 默认情况下,只替换该行第一个匹配到的,输入:

sed 's/wei/youku/' testfile

结果为:

liao ning youku shi, hu nan wei shi
jiang xi youku sliao ning youku shi, hu nan wei shi
jiang xi youku shi, zhe jiang wei shi
jiang su youku shi, ning xia wei shi,hi, zhe jiang wei shi
jiang su youku shi, ning xia wei shi,

这里是flag为空的情况,其实把flag设置为1的效果也是这样,即

sed 's/wei/youku/1' testfile

2) flag设置为数字,比如flag为2,则把相应行中第2个匹配的字符串进行替换。

sed 's/wei/youku/2' testfile

运行后结果为:

liao ning wei shi, hu nan youku shi
jiang xi wei shi, zhe jiang youku shi
jiang su wei shi, ning xia youku shi,

3) flag设置为g,则把该行中所有匹配中的都替换,输入:

sed 's/wei/youku/g' testfile

结果为:

liao ning youku shi, hu nan youku shi
jiang xi youku shi, zhe jiang youku shi
jiang su youku shi, ning xia youku shi,

4) flag设置为p,则会把该行原始内容和修改之后的内容都输出。介绍flag设置p之前,先介绍下-n选项,当sed命令使用-n选项时,会禁止所有的输出。比如输入:

sed -n 's/wei/youku/' testfile

运行后什么都不会输出。但是如果把flag设置成p的话,那么就会把修改过的行打印出来,没有修改的行不打印。输入

sed -n 's/ning/youku/p' testfile 

运行后结果为:

liao youku wei shi, hu nan wei shi
jiang su wei shi, youku xia wei shi,

这里说明-n配置p的使用能把修改的行打印出来。

5) flag设置为w file名这种形式的话,那么会把输出打印到文件中。比如输入:

sed 's/wei/youku/w destfile' testfile

运行发现,生成了一个destfile文件,同时屏幕上也会输出一段修改后的内容,可以发现destfile中的内容和屏幕的内容相同,都为

liao ning youku shi, hu nan wei shi
jiang xi youku shi, zhe jiang wei shi
jiang su youku shi, ning xia wei shi,

注意:如果要替换的原始行中有左斜线的话,对其匹配有两种方法:分别是对左斜线转义和使用感叹号分割。比如website文件中的内容为:

http://www.baidu.com/map/dianshiju/wuzhuang

现在需要修改map/dianshiju/wuzhuang这一整段为gaoxiao/xiangcun/remen
输入:

sed 's/map\/dianshiju\/wuzhuang/gaoxiao\/xiangcun\/remen/' website

运行后结果为:

http://www.baidu.com/gaoxiao/xiangcun/remen

当然,还有一种更好的方法就是使用感叹号做分隔符,输入如下:

sed 's!map/dianshiju/wuzhuang!gaoxiao/xiangcun/remen!' website

运行结果与上面的一样,这个用感叹号分割的方法非常好用,以后如果原始字符串中也有左斜杠的话就用这个吧,我挺满意。

  1. 指定一定范围的行进行处理
    使用sed指令的时候,默认会把整个文件的所有都依次取出来进行匹配,如果想要指定哪些行进行处理的话可以使用以下几种方法。

3.1 指定数字过滤行
sed把文本的第一行编号为1,以此类推,最后一行用$表示,可以单行进行操作或者对一定范围的行进行操作,待处理的文件为testfile,内容如下:

liao ning wei shi, hu nan wei shi
jiang xi wei shi, zhe jiang wei shi
jiang su wei shi, ning xia wei shi,
shan dong wei shi,xi zang wei shi,
si chuan wei shi,chong qing wei shi,
jiang xi wei shi,an hui wei shi

3.1.1 单行操作
比如只把第二行的wei字符串换成youku字符串,输入如下:

sed '2s/wei/youku/' testfile

运行后结果为:

liao ning wei shi, hu nan wei shi
jiang xi wei shi, zhe jiang wei shi
jiang su wei shi, ning xia wei shi,

3.1.2 指定多行
比如把从第二行到第四行的内容第一次出现的为改成youku,输入:

sed '2,4s/wei/youku/' testfile

运行后结果如下:

liao ning wei shi, hu nan wei shi
jiang xi youku shi, zhe jiang wei shi
jiang su youku shi, ning xia wei shi,
shan dong youku shi,xi zang wei shi,
si chuan wei shi,chong qing wei shi,
jiang xi wei shi,an hui wei shi

3.1.3 从指定行一直到最后一行
用美元符号指定到最后一行,比如把从第3行到最后一行内容中所有的wei都改成youku,输入如下:

sed '3,$s/wei/you ku/g' testfile

运行后结果如下:

liao ning wei shi, hu nan wei shi
jiang xi wei shi, zhe jiang wei shi
jiang su you ku shi, ning xia you ku shi,
shan dong you ku shi,xi zang you ku shi,
si chuan you ku shi,chong qing you ku shi,
jiang xi you ku shi,an hui you ku shi

3.2 使用文本过滤行
使用文本过滤可以过滤出只包含目标字符串的行进行处理,这里的优势在于目标字符串可以使用正则表达式[正则表达式后续详谈]。加入要把包含jiang xi这个字符串的行中的所有wei改成yoiuku,输入如下:

sed '/jiang xi/s/wei/you ku/' testfile

运行后结果为:

liao ning wei shi, hu nan wei shi
jiang xi you ku shi, zhe jiang you ku shi
jiang su wei shi, ning xia wei shi,
shan dong wei shi,xi zang wei shi,
si chuan wei shi,chong qing wei shi,
jiang xi you ku shi,an hui you ku shi

注意:多行模式也可以与之前的命令组合,比如之前提到的-e用于多个命令,输入:

sed -e '2,$s/wei/youku/g;3,$s/shi/tengxu/g' testfile

运行后结果为:

liao ning wei shi, hu nan wei shi
jiang xi youku shi, zhe jiang youku shi
jiang su youku tengxu, ning xia youku tengxu,
shan dong youku tengxu,xi zang youku tengxu,
si chuan youku tengxu,chong qing youku tengxu,
jiang xi youku tengxu,an hui youku tengxu
  1. 用sed删除相应行
    之前使用s对相应行的某些内容进行替换,用d(delete)可以删除匹配上的行。
    4.1 删除单行
    比如删除第二行,输入:
sed '2d' testfile

运行后结果为:

liao ning wei shi, hu nan wei shi
jiang su wei shi, ning xia wei shi,
shan dong wei shi,xi zang wei shi,
si chuan wei shi,chong qing wei shi,
jiang xi wei shi,an hui wei shi

4.2 删除指定范围内的行
比如删除从第二行到第四行

sed '2,4d' testfile

运行后结果为:

liao ning wei shi, hu nan wei shi
si chuan wei shi,chong qing wei shi,
jiang xi wei shi,an hui wei shi

4.3 用美元符号表示一直删除到最后一行
比如删除从第二行一直删除到最后一行,输入:

sed '2,$d' testfile

运行后结果为:

liao ning wei shi, hu nan wei shi

4.4 用文本过滤删除
比如删除包含xi zang的行,输入

sed '/xi zang/d' testfile

运行后结果为:

liao ning wei shi, hu nan wei shi
jiang xi wei shi, zhe jiang wei shi
jiang su wei shi, ning xia wei shi,
si chuan wei shi,chong qing wei shi,
jiang xi wei shi,an hui wei shi
  1. 插入和追加
    除了s用于替换,d用于删除外,还可以使用i(insert)用于插入,a(append)用于追加。
    新建目标文件data,内容为:
This is line 1
This is line 2
This is line 3
This is line 4
This is line 5
This is line 6

5.1 在指定行前插入一行
输入:

sed '3i\insert line' data

运行后输出结果为

This is line 1
This is line 2
insert line
This is line 3
This is line 4
This is line 5
This is line 6

5.2 在指定行后面插入一行
输入

sed '4a\append line' data

运行后结果为:

This is line 1
This is line 2
This is line 3
This is line 4
append line
This is line 5
This is line 6

在最后一行后面追加则输入:

sed '$a\append line' data
  1. 修改
    如果需要修改某一行的内容,可以使用c(change)去修改。比如上面的data文件,内容为:
This is line 1
This is line 2
This is line 3
This is line 4
This is line 5
This is line 6

6.1 修改指定的某一行
比如要修改第三行的内容修改为changed line 3,输入:

sed '3c\changed line 3' data

运行后结果为:

This is line 1
This is line 2
changed line 3
This is line 4
This is line 5
This is line 6

6.2 指定字符串去匹配并修改
比如把包含line 3的行改成changed line 3,输入:

sed '/line 3/c\changed line 3' data

运行后结果为:

This is line 1
This is line 2
changed line 3
This is line 4
This is line 5
This is line 6
  1. 字符转换
    字符转换可以一个一个地对字符进行转换,输入模式为:
sed 'y/src/dst/' file

这个命令会把src的第一个字符转化成dst的第一个字符,src的第二个字符转化成dst的第二个字符,依次类推。当发现src和dst的长度不同时,该命令报错。比如value文件的内容为:

This is line 1, num is 134
This is line 2, num is 158
This is line 3, num is 238
This is line 4, num is 849 
This is line 5, num is 666 
This is line 6, num is 899

现在想把所有的2换成7,所有的3换成8,所有的4换成9,输入:

sed 'y/234/789/' value

运行后输出结果为:

This is line 1, num is 189
This is line 7, num is 158
This is line 8, num is 788
This is line 9, num is 899 
This is line 5, num is 666 
This is line 6, num is 899

可以发现,y指令会把搜索所有的对应字符,而不需要加g去全局替换

  1. 打印
    打印文本中的内容有3个方法,第一个方法是使用p来打印一行内容,第二个方法是使用等号(=)打印出来行号,第三个方法是使用小写字母L(l)打印一行。比如文件value的内容为
This is line 1, num is 134
This is line 2, num is 158
This is line 3, num is 238
This is line 4, num is 849 
This is line 5, num is 666 
This is line 6, num is 899

8.1 用字母p打印一行内容
比如输入:

cat value |sed 'p'

运行后输出结果为:

This is line 1
This is line 1
This is line 2
This is line 2
This is line 3
This is line 3
This is line 4
This is line 4
This is line 5
This is line 5
This is line 6
This is line 6

配合-n和p使用,则只把匹配的行打印出来。比如输入

sed -n '/line 4/p' value

运行后输出:

This is line 4

或者输入:

sed -n '1,3p' value

运行后输出结果为:

This is line 1
This is line 2
This is line 3

也可以把很多指令都组合起来,比如输入:

sed -n '/3/{p;s/line 3/substitute 3/p}' value

运行后输出:

This is line 3
This is substitute 3

可以看出这条命令首先使用p把包含3的行打印出来,然后使用把包含line 3的行替换后再打印出来。

8.2 打印出行号
输入:

sed '=' value

运行后结果为:

1
This is line 1
2
This is line 2
3
This is line 3
4
This is line 4
5
This is line 5
6
This is line 6

再比如输入:

sed -n '/line 3/{=;p}' value

运行后结果为:

3
This is line 3

8.3 用-l(小写的L)打印不可打印字符
对于不可打印字符,一般自动使用八进制前加一个反斜线表示,或者使用C语言的命名方法,比如制表符使用\t表示。注意行尾的换行符使用美元符号$表示。输入:

sed -n '/line 2/{l;p}' value

运行后结果为:

This is line 2$
This is line 2
  1. sed写入文件
    写入文件要用w指定,比如把第二行到第四行的内容写到文件test中,输入:
sed '2,4w test' value

查看test中的内容为:

This is line 2
This is line 3
This is line 4

再举例输入:

sed -n '/line 3/w test2' value

运行后查看test2文件,内容为:

This is line 3

10 .总结与展望
10.1 总结
1)sed的输入,可以使用管道或者文件;
2)sed加载指令的时候,可以通过-e指令加载多个命令或者在文件中把命令一行行写好然后用-f指令去加载;
3)sed中使用s去替换字符串;
4)sed中flag的使用,flag默认只针对第一次匹配成功的进行修改;flag为一个数字n的时候,则只针对第n次成功匹配进行修改;flag如果为g则对所有匹配都修改;flag如果为p并且使用-n参数联合使用的话则只打印出修改的行;flag如果为w file则会把修改后的内容写入到file文件中,同时也会打印到终端上。
5) 指定数字过滤出单独行进行操作,用数字过滤一定范围内的行进行操作,用$符号表示到最后一行,使用文本过滤对应行进行操作。
6) 用d指令删除,i指令插入,a指令追加,c指令修改
7)用y指令转换字符串,p打印字符串,=号打印行号,l打印不可打印字符
8)w file把内容写入文件。

10.2 展望
下一节学习使用gwak指令

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

推荐阅读更多精彩内容

  • 第 2 章 SHELL 基础知识2.1 shell脚本我们在上面简单介绍了一下什么是shell脚本,现在我们来进一...
    LiWei_9e4b阅读 1,577评论 0 0
  • 官网 中文版本 好的网站 Content-type: text/htmlBASH Section: User ...
    不排版阅读 4,407评论 0 5
  • 基础命令 主要的命令和快捷键 Linux系统命令由三部分组成:cmd + [options]+[operation...
    485b1aca799e阅读 1,103评论 0 0
  • grep擅长查找,awk擅长分析(select),sed擅长批量编辑行 概述 SED的英文全称是 Stream E...
    piziyang12138阅读 936评论 0 3
  • 鸡汤还是解药不读完怎么知道? 1.关于自卑vs自信? 我,总是很自信 若我问你,我是个什么样的人,自信这两个字肯定...
    夜雨飘然阅读 495评论 1 1