文本处理工具sed - 每天进步一点点

sed介绍
sed(stream editor)是一种非交互式的流编辑器,通过多种转换修改流经它的文本。默认情况下,sed不会改变原文件本身,而只是对流经sed命令的文本进行修改,并将修改后的结果打印到标准输出中。
sed处理文本时是以行为单位的,每处理完一行就立即打印出来,然后再处理下一行,直至全文处理结束。sed可做编辑动作包括删除、查找替换、添加、插入、从其他文件读入数据等。

sed命令使用的场景包括以下一些:
  • 常规编辑器编辑困难的文本。
  • 太过庞大的文本,使用常规编辑器难以胜任(如vi一个几百兆的文件)。
  • 有规律的文本修改,加快文本处理速度(比如说全文替换)。

sed命令的功能十分强大,由于sed本身的复杂度,以及和正则表达式的结合,使用sed命令非常难以掌握。只有不断的多读用,才能深刻的理解和记住sed的功能。
 
sed常用的命令:
sed命令 作用
a 在匹配行后面加入文本
c 字符转换
d 删除行
D 删除第一行
i 在匹配行前面接入文本

h

复制模板块的内容到存储空间
H 追加模板块的内容到存储空间
g 将存储空间的内容复制到模式空间
G 将存储空间的内容追加到模式空间
n 读取下一个输入行,用下一个命令处理新的行
N 追加下一个输入行到模板块后并在二者间插入新行
p 打印匹配的行
P 打印匹配的第一行
q 退出sed
r 从外部文件中读取文本
w 追加写文件
匹配的逆
s/old/new 用new替换正则表达式old
= 打印当前行号

 

 

sed常用的参数:

sed参数 作用
-e 多条件编辑
-h 帮助信息
-n 不输出不匹配的行
-f 指定sed脚本
-V 版本信息
-i 直接修改原文件

 

sed常用的正则表达式匹配:

元字符 作用
^ 匹配行的开始。如:/^cat/匹配所有以cat开头的行
$ 匹配行的结束。如:/cat$/匹配所有以cat结尾的行
. 匹配任一非换行字符。如:/c.t/匹配c后接一个任意字符,然后是t
* 匹配零个或任意多个字符。如:/*cat/匹配一串字符后紧跟cat的所有行
[] 匹配指定范围内的字符。如:/[Cc]at/匹配cat和Cat
[^] 匹配指定范围外的任意单个字符。如:/[^A-Z]/匹配没有大写字母的行
\(..\) 保存匹配的字符。如:s/\(love\)able/\1rs/, loveable被替换成lovers
& 保存搜索字符用来替换其他字符。如:s/love/**&**/,love编程**love**
\< 锚定单词的开始。如:/\<cat/匹配包含以cat开头的单词的行
\> 锚定单词的结尾。如:/cat\>/匹配包含以cat结尾的单词的行
[x\{n\} 重复字符x,m次。如:/o\{5\}/匹配包含5个o的行
x\{m,\} 重复字符x,至少m次。如:/o\{5,\}/匹配至少有5个o的行
x\{n,m\} 重复字符x,至少m次,不多于n次。如:/o\{5,10\}/匹配5到10个o的行
 
 
 
 
下面列出一些sed基本的操作的例子
 
有这么一个文件(sed.txt):
  
  
1
2
3
4
5
6
[ root@ kurol  ~ ]cat  sed. txt
this  is  line  1this  is  First  line
this  is  line  2the  Second  lineEmpty  line  followed
 
this  is  line  4this  is  Third  line
this  is  line  5this  is  Fifth  line

使用sed修改文件流的方法如下:

 
 
1
2
3
4
5
6
sed  [ option ]  ' command '  file
#option sed
#command sed25
#使-e
#sedsed
#sed  


下面的例子演示了将this改为that的同时,还要讲line改为LINE,两个编辑命令前都要使用-e参数,如果有更多的编辑需求,以此类推

 
 
1
2
3
4
5
6
[ root@ kurol  ~ ]sed  - e  ' s/this/that/g '  - e  ' s/line/LINE/g '  sed. txt 
that  is  LINE  1that  is  First  LINE
that  is  LINE  2the  Second  LINEEmpty  LINE  followed
that  is  LINE  4that  is  Third  LINE
that  is  LINE  5that  is  Fifth  LINE  

 

使用分号(;)连接两个都编辑的命令,上面的命令用分号也可达到同样的效果:

 
 
1
2
3
4
5
6
[ root@ kurol  ~ ]sed  ' s/this/that/g ; s/line/LINE/g '  sed. txt 
that  is  LINE  1that  is  First  LINE
that  is  LINE  2the  Second  LINEEmpty  LINE  followed
that  is  LINE  4that  is  Third  LINE
that  is  LINE  5that  is  Fifth  LINE  

 

删除

使用d命令可删除指定的行:

 
 
1
2
3
4
5
6
#file
[ root@ kurol  ~ ]sed  ' 1d '  sed. txt 
this  is  line  2the  Second  lineEmpty  line  followed
this  is  line  4this  is  Third  line
this  is  line  5this  is  Fifth  line

 

由于sed默认不修改原文件,如果希望保存修改后的文件则需要用重定向:

 
 
1
sed  ' 1d '  sed. txt  >  saved_file  

如果想直接修改文件,使用 -i 参数,这样的方式不会有任何输出,而是直接修改了源文件

 
 
1
sed  - i  ' 1d '  sed. txt  


删除指定范围的行 :

 

删除1-3行:

 
 
1
2
3
[ root@ kurol  ~ ]sed  ' 1,3d '  sed. txt
this  is  line  4this  is  Third  line
this  is  line  5this  is  Fifth  line

 

删除第一行当最后一行:

 
 
1
2
[ root@ kurol  ~ ]sed  ' 1,$d '  sed. txt
[ root@ kurol  ~ ]#      #sed.txt

 

删除最后一行:

 
 
1
2
3
4
5
[ root@ kurol  ~ ]sed  ' $d '  sed. txt
this  is  line  1this  is  First  line
this  is  line  2the  Second  lineEmpty  line  followed
this  is  line  4this  is  Third  line

 

删除指定范围以外的行(只保留第五行):

 
 
1
2
[ root@ kurol  ~ ]sed  ' 5!d '  sed. txt
this  is  line  5this  is  Fifth  line

 

 删除所有包含Empty的行:

 
 
1
2
3
4
5
[ root@ kurol  ~ ]sed  ' /Empty/d '  sed. txt
this  is  line  1this  is  First  line
this  is  line  4this  is  Third  line
this  is  line  5this  is  Fifth  line

 

删除空行:

 
 
1
2
3
4
5
[ root@ kurol  ~ ]sed  ' /^$/d '  sed. txt 
this  is  line  1this  is  First  line
this  is  line  2the  Second  lineEmpty  line  followed
this  is  line  4this  is  Third  line
this  is  line  5this  is  Fifth  line  

 

查找替换

使用s命令可将查找到的匹配文本内容替换成新的文本

s命令用于替换文本


将每行第一个line替换成LINE:

 

 
 
1
2
3
4
5
6
[ root@ kurol  ~ ]sed  ' s/line/LINE/ '  sed. txt 
this  is  LINE  1this  is  First  line
this  is  LINE  2the  Second  lineEmpty  line  followed
this  is  LINE  4this  is  Third  line
this  is  LINE  5this  is  Fifth  line

以上只是把每一行的第一个line被替换了,'s/old/new/' 默认情况下只替换第一次匹配到的内容

 

 

将每行匹配到2个line,并改为LINE:

 

 
 
1
2
3
4
5
6
[ root@ kurol  ~ ]sed  ' s/line/LINE/2 '  sed. txt 
this  is  line  1this  is  First  LINE
this  is  line  2the  Second  LINEEmpty  line  followed
this  is  line  4this  is  Third  LINE
this  is  line  5this  is  Fifth  LINE

 

 

s命令利用g选项,可以完成所有匹配值的替换(全文替换):

 

 
 
1
2
3
4
5
6
[ root@ kurol  ~ ]sed  ' s/line/LINE/g '  sed. txt 
this  is  LINE  1this  is  First  LINE
this  is  LINE  2the  Second  LINEEmpty  LINE  followed
this  is  LINE  4this  is  Third  LINE
this  is  LINE  5this  is  Fifth  LINE

 

字符转换

使用y命令可进行字符转换,其作用为将一系列字符逐个地变换为另外一系列字符,基本用法如下:

 
 
1
sed  ' y/old/new/ '  file  

该命令会将file中的o转换为n、l转换成e、d转换成w

注意转换字符和被转换字符的长度要相等,否则sed无法执行

 

将数字1转换为A,2转换为B,4转换为D,5转换为E:

 

 
 
1
2
3
4
5
6
[ root@ kurol  ~ ]sed  ' y/1245/ABDE/ '  sed. txt 
this  is  line  Athis  is  First  line
this  is  line  Bthe  Second  lineEmpty  line  followed
this  is  line  Dthis  is  Third  line
this  is  line  Ethis  is  Fifth  line

 

插入文本

使用ia命令插入文本,其中i代表在匹配行之前插入,而a代表在匹配行之后插入

 

使用i在第二行前插入文本:

 

 
 
1
2
3
4
5
6
7
[ root@ kurol  ~ ]sed  ' 2 i Insert '  sed. txt 
this  is  line  1this  is  First  line
Insert
this  is  line  2the  Second  lineEmpty  line  followed
this  is  line  4this  is  Third  line
this  is  line  5this  is  Fifth  line

 

使用a在第二行后插入文本:

 

 
 
1
2
3
4
5
6
7
[ root@ kurol  ~ ]sed  ' 2 a Insert '  sed. txt 
this  is  line  1this  is  First  line
this  is  line  2the  Second  lineEmpty  line  followed
Insert
this  is  line  4this  is  Third  line
this  is  line  5this  is  Fifth  line

 

在匹配行的上一行插入文本:

 
 
1
2
3
4
5
6
7
[ root@ kurol  ~ ]sed  ' /Second/i\Insert '  sed. txt 
this  is  line  1this  is  First  line
Insert
this  is  line  2the  Second  lineEmpty  line  followed
this  is  line  4this  is  Third  line
this  is  line  5this  is  Fifth  line

 

读入文本

使用r命令可从其他文件中读取文本,并插入匹配行之后

 

将/etc/passwd 中的内容读出放到sed.txt空号之后

 
 
1
2
3
4
5
6
7
8
9
[ root@ kurol  ~ ]sed  ' /^$/r /etc/passwd '  sed. txt
this  is  line  1this  is  First  line
this  is  line  2the  Second  lineEmpty  line  followed
root: x: 0: 0: root: / root: / bin / bash
......
nginx: x: 498: 499: Nginx  web  server: / var / lib / nginx: / sbin / nologin
this  is  line  4this  is  Third  line
this  is  line  5this  is  Fifth  line

 

 

打印

使用p命令可进行打印,这里使用sed命令时一定要加-n参数,表示不打印没关系的行。从之前的例子可以看出,由于sed的工作原理是基于行的,因此每次都有大量的输出。可是这些输出中有一些我们并不需要看到的,而只需要输出匹配的行或者处理过的行就好了。简单来说,打印操作是删除操作的“逆操作”。

 

打印出文件中指定的行:

 
 
1
2
[ root@ kurol  ~ ]sed  - n  ' 1p '  sed. txt 
this  is  line  1this  is  First  line  

 

将the替换成THE,sed实际处理了第二行,其他几行由于没有匹配所以并未真正处理,但是sed的工作原理是基于流的,所以所有流过的行都打印出来了:

 

 
 
1
2
3
4
5
6
[ root@ kurol  ~ ]sed  ' s/the/THE/ '  sed. txt 
this  is  line  1this  is  First  line
this  is  line  2THE  Second  lineEmpty  line  followed
this  is  line  4this  is  Third  line
this  is  line  5this  is  Fifth  line

 

 

使用p命令,则只打印实际处理过的行,简化了输出(使用-n参数):

 

 
 
1
2
[ root@ kurol  ~ ]sed  - n  ' s/the/THE/p '  sed. txt 
this  is  line  2THE  Second  lineEmpty  line  followed

 

写文件

sed本身默认并不改写原文件,而只是对缓存区的文本做了修改并输出到屏幕。所以想保存文件,除了之前提到的两种方法外(使用重定向或-i参数),还可以使用w命令将结果保存到外部指定文件。

 
 
1
2
3
4
5
[ root@ kurol  ~ ]sed  - n  ' 1,2 w output '  sed. txt 
[ root@ kurol  ~ ]#      #output
[ root@ kurol  ~ ]cat  output 
this  is  line  1this  is  First  line
this  is  line  2the  Second  lineEmpty  line  followed

 

sed脚本

在平日的工作中,需要定期对一些文件做分析操作,这种例行的工作往往有一定“标准化” 的操作,比如说先去除文件中所有的空行,然后再全部替换某些字符等,这种过程类似于生产线上程式化的流水作业。事实上,可以把这些动作静态化地写到某个文件中,然后调用sed命令并使用-f参数指定该文件,这样就可以将一系列动作“装载”并应用于指定文件中,这无疑加快了工作效率,这种文件就是sed脚本。

 

如,创建sed.rules脚本文件,该sed脚本的作用是将全文的this改为THAT,并删除所有空号

 
 
1
2
3
4
5
6
7
8
9
[ root@ kurol  ~ ]cat  sed. rules 
s / this / THAT / g
/^$ / d
[ root@ kurol  ~ ]sed  - f  sed. rules  sed. txt     #使-fsed.txt
THAT  is  line  1THAT  is  First  line
THAT  is  line  2the  Second  lineEmpty  line  followed
THAT  is  line  4THAT  is  Third  line
THAT  is  line  5THAT  is  Fifth  line

 

 

 

 

 

 

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值