简单认识Linux中的sed命令

6 篇文章 0 订阅

本文摘录于《Linux命令与shell脚本编程大全》,这是一本不错的书,很适合像我这样的初学者。

sed命令简介

sed命令被称为流编辑器,和普通的交互文本编辑器恰好相反。在交互式的文本编辑器中(比如vim),你可以用键盘来交互式的插入,删除或替换数据中的文本。流编辑器则会在编辑器处理数据之前基于预先提供的一组规则来编辑数据流。sed编辑器会执行下列操作:
(1)一次从输入中读取一行数据;
(2)根据所提供的编辑器命令匹配数据;
(3)按照命令修改流中的数据;
(4)将新的数据输出到STDOUT。
在流编辑器将所有命令与一行数据匹配完毕后,它会读取下一行数据重复这个过程,在流编辑器处理完所有的数据后,它就会终止。

sed命令格式

sed options script file
选项允许你修改sed命令的行为,如下表

选项描述
-e script在处理输入时,将script中指定的命令添加到已有的命令中
-f file在处理输入时,将file中指定的命令添加到已有的命令中
-n不产生命令输出,使用print命令来完成输出

script参数指定了应用于数据流上的单个命令。如果需要用多个命令,要么使用-e选项在命令中指定,要么使用-f选项在单独的命令中指定。

sed命令应用实例

实例一(替换单个内容)
$ echo “This is a test” |sed ‘s/test/big test/’
This is a big test
在这个例子中sed命令使用了s命令。s命令会将test替换为big test,即第二个字符串会替换第一个字符串。

实例二(替换多个内容)
$ cat test.txt
This is a big test.
This is a big test.
This is a big test.
使用sed替换多个字符串
$ sed -e ‘s/big/small/;s/test/qing/’ test.txt
This is a small qing.
This is a small qing.
This is a small qing.
两个命令作用在同一行数据上,命令之间中分号隔开,并且在命令末尾和分号之间不能有空格。

实例三(替换大量内容)
如果需要大量处理sed命令,那么将他们放进文件中是一个更加方便的方式。
$ cat script.sed
s/big/small/
s/dog/cat/
s/a/A/
使用方法:
sed -f script.sed test.txt

替换标记

替换命令再替换多行中的文本时能正常工作,但默认只是替换每行出现的第一处。
要让替换命令替换一行中不同处出现的文本必须使用替换标记(substitution flag)。替换标记会在替换命令字符串后设置。
s/pattern/replacement/flags
有四种可选的替换标记:

替换标记作用
数字表明新文本将替换第几处模式匹配的地方
g表明新文本将会替换所有匹配的文本
p表明原先的内容要打印出来
w file将替换的结果写到文件中

实例一(使用数字替换标记)
$ cat test.txt
This is a test of the test script.
This is the second test of the test script.
$ sed ‘s/test/trial/2’ test.txt
This is a test of the trial script.
This is the second test of the trial script.

实例二(使用替换标记g)
将替换标记指定为g的结果就是,sed编辑器替换文本中匹配模式所匹配的每一处地方。
$ cat test.txt
This is a test of the test script.
This is the second test of the test script.
$ sed ‘s/test/trial/g’ test.txt
This is a trial of the trial script.
This is the second trial of the trial script.

实例三(使用替换标记p)
p替换标记会打印与替换命令中指定的模式匹配的行。这通常会和sed的-n选项一起使用。
$ cat test.txt
This is a test line.
This is a different line.
$ sed -n ‘s/test/trial/p’ test.txt
This is a trial line.
选项-n将禁止sed编辑器输出,但p替换标记会输出修改过的行。

实例四(替换标记w)
w替换标记会产生与p替换标记同样的输出,不过会将输出保存到文件中
$ cat test.txt
This is a test line.
This is a different line.
$ sed ‘s/test/trial/w test1.txt’ test.txt
$
$ cat test1.txt
This is a trial line.

替换字符

sed编辑器容许其他字符代替/字符串分隔符:
$ sed ‘s!/bin/bash!bin/csh!’ /etc/passwd
其中使用了!代替了/。

使用地址

默认情况下,在sed编辑器中使用的命令会作用于文本数据的所有行。如果只想将命令作用于特定行或者某些行,则必须使用行寻址(line addressing)。

在sed编辑中有两种形式的行寻址:
1 以数字形式表示行区间;
2 用文本模式来过滤出行

两种形式都使用相同的格式来指定地址:
[address]command
也可以将特定地址的多个命令分组:
address {
command1
command2
command3
}
sed编辑器会将指定的每条命令作用到匹配指定地址的行上。

1 使用数字方式的行寻址

当使用数字方式的行寻址时,可以用行在文本流中的行的行位置来引用。sed编辑器会将文本流中的第一行编号为1,然后继续按照顺序为接下来的行分配行号。
在命令中指定的地址可以是单个行号,或者是起始行号、逗号以及行号指定的一定区间范围内的行。请看例子:
例1
$ sed ‘2s/dog/cat/’ test1.txt
The quick browm dog.
The quick browm cat.
The quick browm dog.
The quick browm dog.
例2
$ sed ‘2,3s/dog/cat/’ test1.txt
The quick browm dog.
The quick browm cat.
The quick browm cat.
The quick browm dog.
例3
$ sed ‘2,$s/dog/cat/’ test1.txt
The quick browm dog.
The quick browm cat.
The quick browm cat.
The quick browm cat.
小技巧:当不知道有多少行,从开始到结束时,结束位置可以用美元符表示,很方便。

2 使用文本模式过滤器

sed编辑器允许指定文本模式来过滤命令要作用的行。
格式如下:
/pattern/command
必须使用正斜线将要指定的pattern封起来。sed编辑器会将该命令作用到包含指定文本模式的行上。sed编辑器在文本模式采用了正则表达式,使匹配效果更好。当然学会正则表达式是前提。

组合命令使用

例1
$ cat test.txt
The quick browm cat.
The quick browm cat.
The quick browm cat.
The quick browm cat.
$ sed ‘2{s/brown/red/;s/cat/dog/}’ test.txt
The quick browm cat.
The quick red dog.
The quick browm cat.
The quick browm cat.

sed删除行

文本替换命令不是sed编辑器唯一的命令,如果需要删除文本流的特定行,可以使用删除命令。
删除命令d名副其实,它会删除匹配指定寻址模式的所有行。使用该命令时要注意,如果你忘记加入寻址模式的话它会删除所有行。
$ cat test.txt
The quick browm cat.
The quick browm cat.
The quick browm cat.
The quick browm cat.
$ sed ‘d’ test.txt
$
当和指定地址一起使用时,删除命令显然发挥出最大的功用。可以从数据流中删除特定的文本行,指定行号指定:
$ cat test.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
$ sed ‘3d’ test.txt
This is line number 1.
This is line number 2.
This is line number 4.
$
或者使用区间指定:
$ cat test.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
$ sed ‘2,3d’ test.txt
This is line number 1.
This is line number 4.
$
同理可以使用特殊文件结尾字符:
$ cat test.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
$ sed ‘3,$d’ test.txt
This is line number 1.
This is line number 2.
$
sed编辑器的模式匹配也适用于删除
$ cat test.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
$ sed ‘/number 3/d’ test.txt
This is line number 1.
This is line number 2.
This is line number 4.
$
sed编辑器会删掉包含匹配模式的行。
注意:sed编辑器不会修改原始文件,只是在sed编辑器的输出中消失了。原始文件中仍包含哪些行。

插入和附加文本

sed编辑器允许向数据流插入和附加文本行。
1 插入(insert)命令(i)会在指定行前插入一个新行;
2 附加(append)命令(a)会在指定行后增加一个新行。
这两条命令不能在单条命令上同时使用,只能选择插入或者附加。
格式如下:
sed ‘[address]command\new line’

例1
$ echo “test line 2” |sed ‘i\test line 1’
test line 1
test line 2

例2
$ echo “test line 2” |sed ‘a\test line 1’
test line 2
test line 1
显然在参数之前可以指定行数来满足更多的需要,这里就不列举了。请各位多实验。

修改行

修改(change)命令允许修改数据流中整行文本的内容。和插入,附加的命令机制一样只能在单独命令中单个使用。
$ cat test.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
$ sed ‘3c\This is change test.’ test.txt
This is line number 1.
This is line number 2.
This is change test.
This is line number 4.
$
还可以通过匹配的形式进行修改:
$ cat test.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
$ sed ‘/number 3/c\This is change test.’ test.txt
This is line number 1.
This is line number 2.
This is change test.
This is line number 4.
$
注意当使用行数区间修改行内容时,匹配到的所有行都会被修改成一行。具体如下例:
$ cat test.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
$ sed ‘2,3c\This is change test.’ test.txt
This is line number 1.
This is change test.
This is line number 4.
$
注意到了吗?这个不是修改每一行,是修改了所有匹配的行的内容。

转换命令

转换(transform)命令(y)是唯一可以处理单个字符的sed编辑器。
格式如下:
[address]y/inchars/outchars/
转换命令会对inchars和outchars值进行一对一的映射。inchars中的第一个字符会被转换为outchars中的第一个字符,第二个字符会被转换成outchars中的第二个字符。这个映射过程会一直持续到处理完指定字符。如果inchars和outchars的长度不同,则sed编辑器会产生一条错误信息。
例1
$ cat test.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
$ sed ‘y/123/789/’ test.txt
This is line number 7.
This is line number 8.
This is line number 9.
This is line number 4.
注意转换命令是一个全局变量,它会文本行中的所有指定字符自动进行转换,而不会考虑它们出现的位置。

打印使用

有三个命令完成数据流的打印。
1 p命令用来打印文本行;
2 等号(=)命令用来打印行号;
3 l(小写的L)命令用来列出行。

和替换命令中的p标记类似,p命令可以打印sed编辑器输出中的一行。
$ echo “this is a test” |sed ‘p’
this is a test
this is a test
$

其中最常见用法就是打印匹配文本模式的行。
$ cat test.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
$ sed -n ‘number 3/p’ test.txt
This is line number 3.
也可以用行号匹配
$ sed -n ‘2,3p’ test.txt
This is line number 2.
This is line number 3.
$

打印行号(=)

$ cat test.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
$
$ sed ‘=’ test.txt
1
This is line number 1.
2
This is line number 2.
3
This is line number 3.
4
This is line number 4.
结合p打印使用起来非常的方面,例如:
$ cat test.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
$
$ sed -n ‘/number 2/{=;p}’ test.txt
2
This is line number 2.

列出行(l)

列出(list)命令(l)可以打印数据流中的文本不可打印的ASCII 字符。任何不可打印字符要么在其八进制前加一个反斜杠,要么使用标准C风格的命名法(用于常见的不可打印字符),比如\t,来表示制表符。
例如:
$ cat test.txt
This is contains tabs.
ok! ok!
$ sed -n ‘l’ test.txt
This is contains tabs.$
ok!\tok!$
制表符使用\t来表示,行尾换行使用美元符表示,但如果数据流中包含转义字符,列出命令会在必要时使用八进制码来表示。

使用sed处理文件

写入文件

w命令用来写入文件,格式如下:
[address]w filename

filename可以使用相对目录或者绝对目录,不管是哪种,运行sed编辑器的用户必须有文件的写权限。地址可以是sed支持的任意类型的寻址方式,例如单个行号、文本模式、区间号等等。
例1:
$ sed ‘1,2w test.txt’ date.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
$
$ cat test.txt
This is line number 1.
This is line number 2.

如果要根据一些公用的文本值从主文件中创建一份数据文件,比如下面的邮件列表中的,那么w命令会非常好用。
$ cat date.txt
kobe A 24
jordan A 23
james B 23
wode B 3
$ sed -n ‘/23/w 23.txt’ date.txt
$
$ cat 23.txt
jordan A 23
james B 23
哈哈,看懂了吧。只会把匹配的行写入目标文件。

从文件中读取数据

读取(read)命令(r)允许你将一个独立文件中的数据插入到数据流中。
格式如下:
[address]r filename

filename参数指定了数据文件的绝对路径或相对目录。你在读取命令中使用地址区间,只能指定单独一个行号或者文本模式地址。sed编辑器会将文件中的文本插入到指定地址后。
$ cat date.txt
A
B
$
$ cat test.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
$
$ sed ‘3r date.txt’ test.txt
This is line number 1.
This is line number 2.
This is line number 3.
A
B
This is line number 4.
够明显了吧各位!就是这样的效果
再来两个例子
$ cat date.txt
A
B
$ sed ‘/number 2/r date.txt’ test.txt
This is line number 1.
This is line number 2.
A
B
This is line number 3.
This is line number 4.
我想肯定有人会想一个和我一样的问题,匹配到多行怎么办?请看下例:
$ cat date.txt
A
B
$ sed ‘/number/r date.txt’ test.txt
This is line number 1.
A
B
This is line number 2.
A
B
This is line number 3.
A
B
This is line number 4.
A
B
就是这么个情况,请灵活使用。

假如想放在最后面就使用美元符表示就可以了,我就不举例子了,太简单了。

$ sed ‘$r date.txt’ test.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
A
B
$
没办法呀,就这么优秀!

还有一种使用方法是利用另一个文件中的数据来替换文件中的占位文本,这是一个很炫酷的命令。如例:
$ cat date.txt
Would the following people:
List
please report to the ship’s captain.
$ cat date1.txt
kobe
jordan
wode
james
现在我们想将占位文本List放置人物名单的位置。即用人物名单替换List。
$ sed ‘/List/{
> r date1.txt
> d
> }’ date.txt
Would the following people:
kobe
jordan
wode
james
please report to the ship’s captain.

至此sed的基本使用方法就介绍完了!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值