linux三剑客之sed命令

sed是一个非交互式的文件编辑器,可以对文本文件和标准输入进行编辑,标准输入可以来自键盘输入、字符串、文件重定向、管道、变量等。

sed命令选项及其含义

选项含义
-n不打印所有行到标准输出
-e将下一个字符串解析为sed编辑命令,如果只传递一个编辑命令给sed,-e可以省略
-f表示正在调用脚本文件

sed命令通常由定位文本行以及编辑命令组成,编辑命令对定位文本行进行各种处理

sed命令定位文本的方法

选项含义
x指定行号
x,y指定从x到y的行号范围
/a/查询包含a的行
/a/b/查询包含a、b的行
/a/,b从与a匹配的行到b行号之间的行
a,/b/从a行号到匹配到b行之间的行
a,b!查询不包含a行号和b行号行之外的行
^$匹配空行

sed编辑命令选项及其含义

选项含义
p打印匹配行
=打印文件行号
a\在定位行号之后追加文本信息
i\在定位行号之前插入文本信息
d删除定位行
c\用新文本替换定位文本
s使用替换模式替换相应模式
r从另一个文件中读取文本
w将文本写入到一个文件
y变换字符
q第一个模式匹配完成后退出
{}在定位行执行命令组
n读取下一个输入行,用下一个命令处理新的行
h将模式缓冲区的文本复制到保持缓冲区
H 将模式缓冲区的文本追加到保持缓冲区
x互换模式缓冲区和保持缓冲区内容
g 将保持缓冲区的文本复制到模式缓冲区
G 将保持缓冲区的文本追加到模式缓冲区
l显示与八进制ASCII码等价的控制字符

举例如下:

现在有一个文件,文件内容如下:

1.sed命令的-n选项

-p命令表示打印匹配行,如果要打印文件的第一行,可以通过命令如下:

如果不加-n选项可以看到地一行打印出来后,接下来的行都被打印出来,因此可以理解为-n选项是不打印文件的全部内容,但是可以选择性的进行打印,如图:

如果要打印文件的3到6行,可以执行命令如下:

如果要打印匹配Centers的行,注意,匹配是区分大小写的,如果输入centers是无法打印出来的,可以执行的命令如下:

2. sed命令的-e选项:

-e表示将下一个字符串解析为sed编辑命令,如果只传递一个编辑命令,那么-e选项可以省略,换句话说,当传递多个命令时,-e才有用

如果要同时打印包含Centers和everyone的行,传递了两个命令,此时使用-e选项,命令如下:

如果要打印Centers所在的行号,可以通过=来打印,如图:

可以理解为-e选项可以用来同时匹配多个模式,除了-e外,还有通过管道符匹配多个模式

3. sed命令的-f 选项:

-f选项只有在调用sed脚本的时候才起作用,通常将sed命令写入一个脚本中然后通过-f来调用

首先编写sed脚本,脚本的功能是匹配文件a.txt中的Centers行并在其后面插入一句话wo shi hao ren,脚本的名字是append.sed,脚本内容如下:

如上图所示,sed脚本和bash脚本一样以sha-bang(#!)符号开头,后面接解释器的路径,如果不知道sed解释器路径可以执行which sed 查看,-f 表示调用脚本,如果没有 -f 将会报错

给脚本执行权限并执行,执行时后面需要加输入文件,结果如下:

如果脚本中不加入-f 参数那么执行时候,需要通过sed -f 形式,如图:

如果追加的文本有多行,那么需要使用反斜杠符号”\”进行换行,如图:

sed定位文本举例

1.”匹配元字符”:如果匹配的目标字符串中包含元字符,需要用转义符号”\”屏蔽其特殊含义。

例如:匹配a.txt文件中包含.的行,执行命令如下:

2.”使用元字符进行匹配” :sed命令可以使用正则表达式的元字符进行匹配,$在正则表达式中表示行尾,但是在sed中表示最后一行

例如:打印文件a.txt的最后,可以执行命令如下:

也可以将编辑命令p放在单引号外面,两种命令等价,一般放在内部,如图:

注意:如果输入sed -n “$p” a.txt 此时是无法生效的,因此此时双引号中的$p表示引用一个变量,保留变量的内容,如果写成sed -n “$”p a.txt 此时可以生效,此时的$表示一般字符,如果如上图直接写成sed -n ‘$p’ a.txt,在单引号$p将被转义成一般字符$, 可以达到效果,因此sed -n “\$p” a.txt=sed -n ‘$p’ a.txt,注意单引号和双引号的区别

3. “取反符号!” :x,y!表示匹配不在行号x到行号y之间的所有行

例如:打印不在2~5行之间的行,执行命令如下:

4. “使用行号与关键字限定行范围” :与取反类似,只是将x,y通过模式替换

例如:匹配a.txt文件Centers的行到最后一行,执行命令如下:

打印文件第二行到匹配Centers的行,执行命令如下:

sed编辑命令举例

1.”追加文本” : 使用a\,在匹配行的后面追加一组内容

例如:在匹配Centers行的后面追加一组文本内容 I love china,如图:

注意:sed追加文本只是将结果输出到标准输出中,原文件并未改变

2.”插入文本”:使用i\,与追加文本类似,区别在于插入文本是在匹配的行前面插入

例如:在匹配Centers行的前面插入一组文本内容tomorrow,如图:

3.”修改文本”:使用c\,将所匹配的行用新文本替换,注意是行

例如:匹配Centers所在的行,并使用shenzhen替换,如图:

4.”删除文本” :可以将指定的行或者指定的行范围删除,使用d命令

例如:删除文件a.txt的第一行,如图:

删除文件的最后一行,如图:

删除文件a.txt的第1~6行,如图:

删除文件中的空行,命令如下:

sed -i '/^$/d' filename

5.”替换文本” : 将所匹配的字符串用新文本进行替换,与修改文本不同,修改文本是将匹配的行进行修改,而替换文本只是单独替换字符串,使用s命令,全部命令为sed ‘s/被替换的字符串/新字符串/’ 输入文件

sed替换选项及其含义

选项含义
g表示替换文本中所有出现的被替换字符串
p与-n选项结合,只打印替换行
w 文件名表示将输出定向到一个文件

将文件中全部以#开头的行替换为空行,如下:

sed -i '/^#/c\\n' filename

例如:将文本a.txt中的to替换成abcd,如图:

从图中可以看到,有几处被替换,但是有一处没有替换,原因是因为在执行命令时如果后面没有加g参数那么只替换每行出现的第一个单词,如果加了g参数那么所有出现的都会被替换,加g参数再次执行命令,如图:

如果只打印替换的行,此时需要使用-n 以及p选项,如图:

替换命令还可以替换第几次出现的字符串,只需要在最后加上数字

例如: 替换第二次出现的to,将其替换成abc,执行命令如下:

w选项比较简单,只是将替换后的文本行重新写入一个文件中,如果没有此文件将新建,例如将上图中第二次出现的to替换成abc后,写入到文件b.txt中,执行命令

查看文件b.txt可以看到文件中只包含替换的行,如图:

sed命令只是将改动输出到标准输出中,并未修改原文件,如果要保存改动后的文件,需要将编辑后的文本重定向到另一个文件中,此时可以使用编辑命令的w选项,这个与替换文本中的w选项类似

例如:打印文件a.txt中的第1~5行,并重定向到c.txt文件中,如图:

查看c.txt文件内容显示的刚好是前5行内容,如图:

sed命令还可以将其他文本内容读取过来,添加到指定文本之后

例如:从b.txt文件中读取数据,添加到匹配Centers字符串的行之后,如图:

sed命令的q选项表示完成指定匹配后立即退出,格式为:指定地址 q

例如:要打印前5行然后立即退出可以指定sed ‘5 q’ a.txt即可

sed命令的y选项表示变换命令,将一系列字符换成相应的新字符,是对字符的逐个处理,格式为: sed ‘y/被变换字符/新字符/’ 文件

例如:将Centers变换成abcdefg,注意位数要保持一致,如图:

附加:

1、关于换行符的问题:

如果在windows下编辑了shell脚本,放在linux后执行会报语法错误,通过命令查看当前的换行符格式:

在Windows下每一行结尾是\n\r,而Linux下则是\n,所以才会有多出来的\r,把一个文件从一种系统移到另一种系统,就有换行符的问题,也就是上图中的^M字符,如果是unix换行符就只显示$,没有^M

解决方法一:

通过vim打开文件,在普通模式下输入如下内容:

:set ff=unix  告诉 vim 编辑器,使用unix换行符,如果:set ff=dos 表示使用windows换行符

解决方法二:

将每一行结尾的\r替换为空行

sed -i ‘s/\r$//’ file.sh

从上图可以看出,执行sed命令后,脚本中的换行符已经变成了unix换行符$

标签