sed是一个脚本型的编辑器,是非交互式的编辑器,也就是说sed与常见的编辑器不同(比如说vim),sed没有交互式的编辑界面以及光标移动或者庞大的快捷键/功能,sed 的使用就是很简单的一个脚本行。
sed 作为编辑器有如下特点让人难以拒绝:
(1) 非交互,基于模式匹配的过滤及修改文本
(2) 逐行处理,所以那些对舒适的交互式编辑而言太大的文件使用sed 会显得格外有优势
(3) 可实现对文本的输出、删除、替换、复制、剪切、导入、导出等各种编辑操作
(4) 脚本化,在shell 脚本编程中你总不能打开vim 吧?
模式空间
默认不编辑原文件,仅对模式空间中的数据做处理;而后,处理结束后,将模式空间打印至屏幕;
#sed [options] 'AddressCommand' file ...
sed 选项 '动作' 文件名
前置命令(eg.cat 文件名) | sed 选项 '动作'
选项:
-n :静默模式,不再默认显示模式空间中的内容只显示被修改的行的内容
-e SCRIPT -e SCRIPT:可以同时执行多个脚本
-f :直接将 sed 的动作写在一个文件内, -f filename 则可以运行 filename 内的 sed 动作;
-r :sed 的动作支持的是延伸型正规表示法的语法。(默认是基础正规表示法语法)
-i :直接修改读取的文件内容,而不是输出到终端。
#注意
命令需要用单引号或者双引号引起来号;
当你的命令中字符需要用到单引号时,是无法通过 '\' 来转义的,此时使用命令用双引号引起来即可。
用到正则时需要用 '/' 进行标记
[address1[,address2]]动作/pattern/replacement/[flags]
///
还可以使用’@@@'进行分割首先说明[address1[,address2]]
可以不存在
#sed -n '3p' xxx.txt
3p 打印第三行,p 功能为打印
-n 表示静默模式,一般sed都有把所有读到的行打印出来,如果不加这个参数,它将一行行打印读到的,并且由于 3p 会重复打印第三行;
#打印最后一行
sed -n '$p' xxx.txt
# 打印从N行开始到最后一行
sed -n 'N,$p' xxx.txt
#使用 + 操作符来间接寻址,表示从某行开始向下多少行
sed -n 'N,+2p' xxx.txt
#使用 ~ 指定地址范围,它使用N~M 的形式,它告诉SED应该处理N行开始的每M行
sed -n 'N~M p' xxx.txt
#使用正则表达式匹配指定的行,注意必须用正斜杠将正则表达式封起来
sed -n '/正则表达式/p' xxx.txt
#上面可以结合使用
sed -n '/正则表达式/,N~M p' xxx.txt
#两个正则匹配
sed -n '/正则表达式1/,/正则表达式2/p' xxx.txt
^
表示一行的开头。如:/^#/
以#开头的匹配。$
表示一行的结尾。如:/}$/
以}结尾的匹配。\<
表示词首。 如:\ 表示以 abc 为首的詞。
\>
表示词尾。 如:abc\>
表示以 abc 結尾的詞。.
表示任何单个字符。*
表示某个字符出现了0次或多次。[ ]
字符集合。 如:[abc]
表示匹配a或b或c,还有 [a-zA-Z]
表示匹配所有的26个字符。如果其中有^表示反,如 [^a]
表示非a的字符a :在指定行后 新增一行或多行内容
c :替换指定行的内容
d :删除指定行的内容
i :在指定行之前 插入一行或多行内容
s :替换指定内容
n : 获取下一行命令
p : 显示符合条件的行;
r FILE: 将指定的文件的内容添加至符合条件的行处
w FILE: 将地址指定的范围内的行另存至指定的文件中;
暂存和取用的命令:H h G g
命令格式的 flag 部分,后面出现 /g
表示改行出现的所有匹配内容都进行替换。如果不指定 flag 将默认只对改行匹配到的第一个做更改。
除此之外还提供了其它几个命令
p
只输出匹配到的行,再行寻址里面已经用过w
存储改变的行到文件,比如sed -n 's/i/I/w junk.txt' books.txt
i
匹配时忽略大小写$ echo "hello,world" | sed "s/hello/hi/"
hi,world
$ echo "hello,world" > file
$ sed 's/hello/hi/' file
hi,world
1、删除行内容删除第2行的内容
cat file.txt | sed '2d'
sed '2d' file.txt
2、删除第2-5行的内容
cat file.txt | sed '2,5d'
sed '2,5d' file.txt
3、删除第2行到最后一行的内容
cat file.txt | sed '2,$d'
sed '2,$d' file.txt
1、在第2行后新增内容
2、在第2行前插入内容
3、在第2行后新增2行内容
1、把第2行的内容替换为 hello world
2、把第2-5行的内容替换为 hello world
3、只显示被修改的行的内容
1、搜索含有abc的行
2、搜索并删除指定内容
1、默认只替换每行中模式首次匹配的内容
2、g标记可以使sed执行全局替换
3、g标记可以使sed替换第N次出现的匹配
1、直接删除文件内容
sed -i '2,5d' file
2、直接替换文件内容
sed -i 's/abc/xxx/g' file
1、搜索并删除空行
sed '/^$/d' file.txt
2、替换3位数的数字
[root@linuxprobe test_shell]# cat b.txt
a 1 b 22 c 333 d 4444
[root@linuxprobe test_shell]# sed 's/\b[0-9]\{3\}\b/666/g' b.txt
a 1 b 22 c 666 d 4444
[root@linuxprobe test_shell]# cat file
a1
b22
c333
d4444
ab12abc123abcd1234
[root@linuxprobe test_shell]# sed 's/[0-9]\{3\}/666/g' file
a1
b22
c666
d6664
ab12abc666abcd6664
3、操作文件内容时,备份原文件
[root@linuxprobe test_shell]# cat file
xxx 123 xxx123 123xxx
[root@linuxprobe test_shell]# sed -i.bak 's/abc/xxx/g' file
[root@linuxprobe test_shell]# cat file
xxx 123 xxx123 123xxx
[root@linuxprobe test_shell]# ls
b.txt file file.bak test.sh
[root@linuxprobe test_shell]# cat file.bak
xxx 123 xxx123 123xxx
4、已匹配字符串标记( & )
在 sed 中 & 指代模式所匹配到的字符串
[root@linuxprobe test_shell]# cat file
abc 123 abc123 123abc
[root@linuxprobe test_shell]# sed 's/abc/[&]/g' file
[abc] 123 [abc]123 123[abc]
5、子串匹配标记( \1 \2 \3 …)
在sed中 \1 \2 \3 指代出现在括号中的部分正则表达式所匹配到的内容
[root@linuxprobe test_shell]# echo abc 123 | sed 's/abc \([0-9]\)/\1/'
123
对于匹配到的第一个子串,其对应的标记是 \1 ,匹配到的第二个子串是 \2 ,往后以此类推。
[root@linuxprobe test_shell]# echo HELLO world | sed 's/\([A-Z]\+\) \([a-z]\+\)/\2 \1/'
world HELLO
6、组合多个表达式
[root@linuxprobe test_shell]# echo abc 123 | sed 's/[a-z]\+/xxx/' | sed 's/[0-9]\+/666/'
xxx 666
[root@linuxprobe test_shell]# echo abc 123 | sed 's/[a-z]\+/xxx/;s/[0-9]\+/666/'
xxx 666
[root@linuxprobe test_shell]# echo abc 123 | sed 's/[a-z]\+/xxx/;s/[0-9]\+/666/'
xxx 666
7、引用变量
[root@linuxprobe test_shell]# echo user | sed "s/user/$USER/"
root
备注:在双引号中,可以引用变量。
8.删除配置文件中注释行
#号
sed -ri '/^[ \t]*#/d' u.txt
//号
sed -ri '#^[ \t]*//#d' u.txt
无内容行
sed -ri '/^[ \t]*$/d' u.txt
sed -ri '/^[ \t]*($|#)/d' u.txt 合并
9、删除/etc/grub.conf文件中行首的空白符
sed -r 's@^[[:spapce:]]+@@g' /etc/grub.conf
sed 's/^\ \+//' /etc/grub.conf
10、替换/etc/inittab文件中"id:3:initdefault:"一行中的数字为5
sed 's@id:id:[0-9]:initdefault::initdefault:@\15\2@g' /etc/inittab
sed -r 's@(id:)[0-9](:initdefault:)@\15\2@g' /etc/inittab
11、删除/etc/inittab文件中的空白行;
sed '/^$/d' /etc/inittab
12、删除/etc/inittab文件中开头的#号;
sed 's@^#@@g' /etc/inittab
13、删除某文件中开头的#号及后面的空白字符,但要求#号后面必须有空白字符;
sed -r 's@^#[[:space:]]+@@g' /etc/inittab
14、删除某文件中以空白字符后面跟#类的行中的开头的空白字符及#
sed -r 's@^[[:space:]]+#@@g' /etc/inittab
sed 's/^\ \+#//' /etc/inittab
15、取出一个文件路径的目录名称;
echo "/etc/rc.d/" | sed -r 's@^(/.*/)[^/]+/?@\1@g'
取出基名:
echo "/etc/rc.d/" | sed -r 's@^/.*/([^/]+)/?@\1@g'