1.简介
sed全名为 stream editor,流编辑器。是一种在线编辑器。可以逐行对文件的特定内容进行编辑或打印。
2. 定址
对特定行进行处理,比如1-10行,偶数行,或者是包含"hello"字符串的行,这里把这个定位指定的行叫做"定址"。包括数字定址和正则定址。
数字定址由数字构成,以逗号分隔。如1,3表示1,2,3行,美元符号($)表示最后一行。示例如下:
sed –n ‘2,4s/hello/A/’ message
s表示替换,即对名为message的文件执行命令,将第2-4行中hello字符串替换为A,其它行如果有hello也不会被替换。
正则定址通过正则表达式的匹配来确定需要处理哪些行,示例如下:
sed -n ‘/hello/d’ message
d表示删除,即对名为message的文件执行命令,将匹配到hello的行删除。
3. 执行方式及常见命令
调用sed命令有两种形式:
sed [options] 'command' file(s) ---直接运行命令
sed [options] -f scriptfile file(s) ---运行sed脚本
需注意sed脚本命令的末尾不能有任何空白或文本。当一行多个命令时,要用分号分隔。以#开头的行为注释行。
command:
a:在当前行后面加入一行文本。
b lable :分支到脚本中带有标记的地方,如果分支不存在则分支到脚本的末尾。
c:用新的文本改变本行的文本。
d :从模板块(Pattern space)位置删除行。
D:删除模板块的第一行。
i\ :在当前行上面插入文本。
h :拷贝模板块的内容到内存中的缓冲区。
H :追加模板块的内容到内存中的缓冲区
g :获得内存缓冲区的内容,并替代当前模板块中的文本。
G :获得内存缓冲区的内容,并追加到当前模板块文本的后面。
l :列表不能打印字符的清单。
n :读取下一个输入行,用下一个命令处理新的行而不是用第一个命令。
N :追加下一个输入行到模板块后面并在二者间嵌入一个新行,改变当前行号码。
p :打印模板块的行。
P :打印模板块的第一行。
q :退出Sed。
r file :从file中读行。
t label :if分支,从最后一行开始,条件一旦满足或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾。
T label :错误分支,从最后一行开始,一旦发生错误或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾。
w file :写并追加模板块到file末尾。
W file :写并追加模板块的第一行到file末尾。
! :表示后面的命令对所有没有被选定的行发生作用。
s/re/string :用string替换正则表达式re。
= :打印当前行号码。
# :把注释扩展到下一个换行符以前。
以下的是替换标记
g:表示行内全面替换。
p:表示打印行。
w:表示把行写入一个文件。
x:表示互换模板块中的文本和缓冲区中的文本。
y:表示把一个字符翻译为另外的字符(但是不用于正则表达式)
主要Options 有:n , i , c, f, e, l, h, V
-i, 修改后文件替换原文件
-c: 保持文件归属不变, 需要和-i 同时使用
-n, 不输出原文件,只输出命令执行后的结果
-f, 使用sed脚本文件
-e,允许多条命令,每个命令前都加-e就行
-l,指定行长度,超过设定的长度后换行,必须和'l'命令一块使用
-h, 打印帮助,并显示bug列表的地址。
-V, 打印版本和版权信息。
4. 元字符集
^
锚定行的开始 如:/^sed/匹配所有以sed开头的行。
$
锚定行的结束 如:/sed$/匹配所有以sed结尾的行。
.
匹配一个非换行符的字符 如:/s.d/匹配s后接一个任意字符,然后是d。
*
匹配零或多个字符 如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行。
[]
匹配一个指定范围内的字符,如/[Ss]ed/匹配sed和Sed。
[^]
匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行。
\(..\)
保存匹配的字符,如s/\(love\)able/\1rs,loveable被替换成lovers。
&
保存搜索字符用来替换其他字符,如s/love/**&**/,love这成**love**。
\<
锚定单词的开始,如:/\
\>
锚定单词的结束,如/love\>/匹配包含以love结尾的单词的行。
x\{m\}
重复字符x,m次,如:/0\{5\}/匹配包含5个o的行。
x\{m,\}
重复字符x,至少m次,如:/o\{5,\}/匹配至少有5个o的行。
x\{m,n\}
重复字符x,至少m次,不多于n次,如:/o\{5,10\}/匹配5--10个o的行。
5.实例
删除:d命令
sed /^$/d filename -----删除文件中的空行,^和$分别锚定行的开始和结束。
sed /^[[:space:]]*$/d filename -----删除内容为多个空格/tab组成的行。
sed '2,$d' example-----删除example文件的第二行到末尾所有行。
sed '/test/'d example-----删除example文件所有包含test的行。
替换:s命令
sed 's/test/mytest/g' example-----在整行范围内把test替换为mytest。如果没有g标记,则只有每行第一个匹配的test被替换成mytest。
sed -n 's/^test/mytest/p' example-----(-n)选项和p标志一起使用表示只打印那些发生替换的行。
sed 's/^192.168.0.1/&localhost/' example-----&符号表示保留字符串中被找到的部份。
sed -n 's/\(love\)able/\1rs/p' example-----love被标记为1,所有loveable会被替换成lovers,而且替换的行会被打印出来
sed -i '/matchStr/{n;s/str1/str2/}' fileName -----找到含matchStr的行,将其下一行的str1替换为str2.(注意:有的资料里最后大括号前面有个分号,不能执行成功。最后不能带分号,只有n后面需要分号。)
选定行的范围:逗号
sed -n '5,/^test/p' example-----打印从第五行开始到第一个包含以test开始的行之间的所有行。
覆盖行: c命令
sed -i '/version=/c version=6.1.1' filename -- ‘version=6.1.1’ 整个覆盖到含‘version=’的行
6. 扩展
1.在s命令后面的字符就是查找串和替换串之间的分隔符。分隔符默认为正斜杠,但是可以改变。无论什么字符(换行符,反斜杠外),只要紧跟在s命令,就成了新的串分隔符。这个方法在查找包含正斜杠模式时很管用,比如:查找路径名或生日。用#做分隔符示例如下:
sed 's#1999/12/23#2999/10/02#g' filename
2.有时使用其它命令,也可达到同样效果,如下面3句话的效果完全一样:
cat filename | sed –n ‘/1024/p’
sed -n '/1024/p' filename
grep '1024' filename
即打印出文件中匹配“1024”的所有行。
参考文档:
Linux命令:sed -i 解析、sed是什么、工作原理、基本语法使用、数字和正则定址、基本子命令以及最常用子命令 s 的用法 - 古兰精 - 博客园