Sed 命令详解
一、简介
sed是非交互式的流编辑器。它不会修改文件,除非使用shell重定向来保存结果。默认情况下,所有的输出行都被打印到屏幕上。
sed编辑器逐行处理文件(或输入),并将结果发送到屏幕。具体过程如下:首先sed把当前正在处理的行保存在一个临时缓存区中(也称为模式空间),然后处理临时缓冲区中的行,完成后把该行发送到屏幕上。sed每处理完一行就将其从临时缓冲区删除,然后将下一行读入,进行处理和显示。处理完输入文件的最后一行后,sed便结束运行。sed把每一行都存在临时缓冲区中,对这个副本进行编辑,所以不会修改原文件。
sed命令格式
sed [options] 'command' file(s)
sed [options] -f scriptfile file(s)
sed命令选项
选项 | 功能 |
---|---|
-e | 直接在命令行模式上进行sed动作编辑,此为默认选项 |
-f | 将sed的动作写在一个文件内,用–f filename 执行filename内的sed动作 |
-i | 直接修改文件内容 |
-n | 只打印模式匹配的行 |
-r | 支持扩展正则表达式 |
-h --help | 显示帮助 |
-v --version | 显示版本信息 |
sed常用命令
命令 | 功能 |
---|---|
a\ | 在当前行下面插入文本 |
i\ | 在当前行上面插入文本 |
c\ | 把选定的行改为新的文本 |
d | 删除,删除选择的行 |
D | 删除模板块的第一行 |
s | 替换指定字符 |
h | 拷贝模板块的内容到内存中的缓冲区 |
H | 追加模板块的内容到内存中的缓冲区 |
g | 获得内存缓冲区的内容,并替代当前模板块中的文本 |
G | 获得内存缓冲区的内容,并追加到当前模板块文本的后面 |
l | 列表不能打印字符的清单 |
n | 读取下一个输入行,用下一个命令处理新的行而不是用第一个命令 |
N | 追加下一个输入行到模板块后面并在二者间嵌入一个新行,改变当前行号码 |
p | 打印模板块的行 |
P | 打印模板块的第一行 |
q | 退出Sed |
b | lable 分支到脚本中带有标记的地方,如果分支不存在则分支到脚本的末尾 |
r | file 从file中读行 |
t | label if分支,从最后一行开始,条件一旦满足或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾 |
T | label 错误分支,从最后一行开始,一旦发生错误或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾 |
w | file 写并追加模板块到file末尾 |
W | file 写并追加模板块的第一行到file末尾 |
! | 表示后面的命令对所有没有被选定的行发生作用 |
= | 打印当前行号 |
# | 把注释扩展到下一个换行符以前 |
sed替换标记
标记 | 作用 |
---|---|
g | 行内全局替换 |
p | 打印行 |
w | 把行写入一个文件 |
x | 互换模板块中的文本和缓冲区中的文本 |
y | 把一个字符翻译为另外的字符(但是不用于正则表达式) |
\1 | 子串匹配标记 |
& | 已匹配字符串标记 |
sed元字符集
与grep一样,sed也支持特殊元字符,来进行模式查找、替换。不同的是,sed使用的正则表达式是括在斜杠线"/"之间的模式。
如果要把正则表达式分隔符"/"改为另一个字符,比如o,只要在这个字符前加一个反斜线,在字符后跟上正则表达式,再跟上这个字符即可。例如:
sed -n '\o^Myop' datafile
元字符 | 作用 | 示例 |
---|---|---|
^ | 行首定位符 | /^my/ 匹配所有以my开头的 |
$ | 行尾定位符 | /my$/ 匹配所有以my结尾的行 |
. | 匹配除换行符外的单个字符 | /m..y/ 匹配包含字母m,后跟两个任意字符,再跟字母y的行 |
* | 匹配零个或多个前导字符 | /my*/ 匹配包含字母m,后跟零个或多个y字母的行 |
[] | 匹配指定字符组内的任一字符 | /[Mm]y/ 匹配包含My或my的行 |
[^] | 匹配不在指定字符组内的任一字符 | /[^A-RT-Z]ed/ 匹配非A-R和T-Z开头,紧跟ed的行 |
\(..\) | 保存已匹配的字符 | s/I\(love\)\(you\)/\2\1me Iloveyou -> youloveme |
& | 保存查找串以便在替换串中引用 | s/love/**&**/,love -> **love** |
\< | 词首定位符 | /\<my/ 匹配包含以my开头的单词的行 |
\> | 词尾定位符 | /my\>/ 匹配包含以my结尾的单词的行 |
x\{m\} | 重复字符x,m次 | /0\{5\}/匹配包含5个0的行 |
x\{m,\} | 重复字符x,至少m次 | /0\{5,\}/匹配至少有5个0的行 |
x\{m,n\} | 重复字符x,至少m次,不多于n次 | /0\{5,10\}/匹配5~10个0的行 |
二、sed 定址
定址用于决定对哪些行进行处理。地址的形式可以是数字、正则表达式、或二者的结合。如果没有指定地址,sed将处理输入文件的所有行。
地址如果是一个数字,则表示某一行号;“$"符号表示最后一行。
地址如果由逗号分隔,则表示处理两行之间的范围(包括这两行在内)。
# 只打印第三行
sed -n '3p' datafile
# 删除第二至第五行
sed -i '2,5d' datafile
# 删除包含'My'的行到包含'You'的行之间的行
sed -i '/My/,/You/d' datafile
# 删除包含'My'的行道第十行之间的行
sed -i '/My/,10d' datafile
三、sed命令详解
3.1 p 命令
命令p用于显示模式空间的内容。默认情况下,sed把输入行打印在屏幕上,选项-n用于取消默认的打印操作。当选项-n和命令p同时出现时,sed可打印选定的内容。
# 选项-n取消sed默认的打印,p命令把匹配模式my的行打印一遍
sed -n '/my/p' datafile
3.2 d 命令
命令d用于删除输入行。sed先将输入行从文件复制到模式空间里,然后对该行执行sed命令,最后将模式空间里的内容显示在屏幕上。如果发出的是命令d,当前模式空间里的输入行会被删除,不被显示。
#删除包含my的行,其余的都被显示
sed '/my/d' datafile
3.3 s 命令
命令s用于替换文本中的字符串,使用后缀 /g
标记会替换每一行中的所有匹配
# 取消默认输出,处理1到20行中匹配以My结尾的行,把行内所有的My替换为You,并打印到屏幕上
sed -n '1,20s/My$/You/gp' datafile
紧跟在s命令后的字符就是查找串和替换串之间的分隔符。分隔符默认为正斜杠,但可以改变。无论什么字符(换行符、反斜线除外),只要紧跟s命令,就成了新的串分隔符。
sed 's#My#Your#g' datafile
3.4 e 选项
-e
是编辑命令,用于sed执行多个编辑任务的情况。在下一行开始编辑前,所有的编辑动作将应用到模式缓冲区中的行上。
sed -e '1,3d' -e 's/My/Your/g' datafile
选项-e用于进行多重编辑。第一重编辑删除第1-3行。第二重编辑将出现的所有My替换为Your。因为是逐行进行这两项编辑(即这两个命令都在模式空间的当前行上执行),所以编辑命令的顺序会影响结果。
3.5 r 命令
r命令是读命令。sed使用该命令将一个文本文件中的内容加到当前文件的特定位置上。
#如果在文件datafile的某一行匹配到模式My,就在该行后读入文件introduce.txt的内容。如果出现My的行不止一行,则在出现My的各行后都读入introduce.txt文件的内容。
sed '/My/r introduce.txt' datafile
3.6 w 命令
# 在example中所有包含test的行都被写入file里
sed -n '/test/w file' example
3.7 a\
命令
a\
命令是追加(行下)命令,追加将添加新文本到文件中当前行(即读入模式缓冲区中的行)的后面。所追加的文本行位于sed命令的下方另起一行。如果要追加的内容超过一行,则每一行都必须以反斜线结束,最后一行除外。最后一行将以引号和文件名结束。
# 将 this is a test line 追加到 以test 开头的行后面
sed '/^test/a\this is a test line' file
3.8 i\
命令
i\
命令是插入(行上)命令,在当前行的前面插入新的文本。
# 将 this is a test line 追加到以test开头的行前面
sed '/^test/i\this is a test line' file
3.9 c\
命令
sed使用该命令将已有文本修改成新的文本。
3.10 n命令
sed使用该命令获取输入文件的下一行,并将其读入到模式缓冲区中,任何sed命令都将应用到匹配行紧接着的下一行上。
# 如果匹配到test,则移动至下一行,将此行中的My替换为Your,然后继续
sed '/test/{n;s/My/Your/;}' datafile
如果需要使用多条命令,或者需要在某个地址范围内嵌套地址,就必须用花括号将命令括起来,每行只写一条命令,或者用分号分割同一行中的多条命令。
3.11 y命令
该命令与UNIX/Linux中的tr命令类似,字符按照一对一的方式从左到右进行转换。例如,y/abc/ABC/将把所有小写的a转换成A,小写的b转换成B,小写的c转换成C。
# 把1~10行内所有abcde转变为大写
sed '1,10y/abcde/ABCDE/' file
# y命令对正则表达式元字符不起作用
# 与s命令的分隔符一样,斜线可以被替换成其它的字符
3.12 q命令
q命令将导致sed程序退出,不再进行其它的处理。
sed '/abcd/{s/abcd/ABCD/;q;}' datafile
3.13 h命令和g命令
在sed处理文件的时候,每一行都被保存在一个叫模式空间的临时缓冲区中,除非行被删除或者输出被取消,否则所有被处理的行都将打印在屏幕上。接着模式空间被清空,并存入新的一行等待处理。
ed -e '/test/h' -e '$G' file
在这个例子里,匹配test的行被找到后,将存入模式空间,h命令将其复制并存入一个称为保持缓存区的特殊缓冲区内。第二条语句的意思是,当到达最后一行后,G命令取出保持缓冲区的行,然后把它放回模式空间中,且追加到现在已经存在于模式空间中的行的末尾。在这个例子中就是追加到最后一行。简单来说,任何包含test的行都被复制并追加到该文件的末尾。
3.14 sed 脚本
sed脚本是一个sed的命令清单,启动Sed时以-f选项引导脚本文件名。Sed对于脚本中输入的命令非常挑剔,在命令的末尾不能有任何空白或文本,如果在一行中有多个命令,要用分号分隔。以#开头的行为注释行,且不能跨行。
四、sed 实例
4.1 sed 开关注释行
# 注释行
sed -i 's/^PasswordAuthentication/#&/' /etc/ssh/sshd_config
sed -i '/PasswordAuthentication/s/^/#/' /etc/ssh/sshd_config #这种方式不太推荐
# 取消注释行
sed -i 's/^#\(PasswordAuthentication.*\)/\1/' /etc/ssh/sshd_config
sed -i '/PasswordAuthentication/s/#//' /etc/ssh/sshd_config #这种方式不太推荐