三剑客之 sed

简介: 三剑客之 sed

本文参考文献:

sed, a stream editor (gnu.org)

awk 于1977年出生,今年45岁,sed 比 awk 大 2-3 岁(比我大23岁...)

sed全名叫 stream editor,流编辑器,用程序的方式来编辑文本

今天这篇文章主要目的还是为了引起大家对 sed 的兴趣,对于这个上古神器还需要大家自行去查阅相关文档去进一步学习

废话少说,开始今天的 sed 学习之旅吧!

# sed 语法
sed [-nefr] [动作]
-n:只输出匹配到的内容
-e:直接在命令行上进行 sed 的动作
-f:将执行 sed 后的结果重定向到一个文件里,f filename 則可以执行 filename 內的 sed 动作
-r:支持扩展正则表达式
-i:对文件直接修改,而不是只输出到屏幕

sed 的(动作)

  • a:添加;a 后面可以接字符串,这些字符串会在新的一行出现(目前的下一行)
  • c:替换;c 后面可以接字串,这些字串可以取代 n1,n2 之间的行(替换行)
  • d:删除
  • i:添加;i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行)
  • p:打印;将某个匹配到的数据印出。通常 p 会与 sed -n 一起出现
  • s:替换;字符串替换

1.替换(s,c)

替换一般涉及到文本内容修改,需要加上 -i 动作

以 test.txt 为例子

root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin

以行为单位的替换

1、将 2 到 5 行的内容替换成 ”NO 2-5 NUMBER“

sed -i '2,5c NO 2-5 NUMBER' test.txt
root:x:0:0:root:/root:/bin/bash
NO 2-5 NUMBER
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin

以字符串为单位的替换

sed 's/要被取代的字串/新的字串/g'

PS:加上 p 是指全部替换,不加的话只对第一个匹配到的字符串进行替换,后续的不进行替换

1、将 root 替换成 noroot(非全局替换)

sed -i 's/root/noroot/' test.txt

可以看到只替换了第一个匹配到的 root

noroot:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/noroot:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin

2、将 root 替换成 noroot(全局替换)

sed -i 's/root/noroot/g' test.txt
noroot:x:0:0:noroot:/noroot:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/noroot:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin

3、替换路径

有些内容(比如说文件路径)会有 "/" 符号,这时候我们就需要转义符避免系统识别错误

例如下面一段内容:

cat path.txt
/var/log/app1/app1.log

我们需要将路径中的 /root/log/app1/app1.log 替换成 /home/log/app1/app1.log

方法一:多次替换

sed -i  -e 's/app1/app2/g' -e 's/root/home/g' path.txt

方法二:使用 # 作为分隔符

这样可以避免转义问题

sed -i -e 's#/root/log/app1/app1.log#/home/log/app2/app2.log#' path.txt

方法三:直接使用转义字符(这个看着比较晦涩,个人建议使用方法2)

sed -i  -e 's/\/root\/log\/app1\/app1.log/\/home\/log\/app2\/app2.log/' path.txt

4、将文本中的 Windows 换行符替换成 UNIX 换行符

我们知道,windows 系统的换行符跟 Linux 系统(Unix类系统)的换行符是不一致的

Unix 系统里,每行结尾只有 “<换行>”,即 “\n”;Windows 系统里面,每行结尾是“ <回车><换行>”,即“\r\n”

一个直接后果是,Unix 系统下的文件在 Windows 里打开的话,所有文字会变成一行

而 Windows 里的文件在 Unix 下打开的话,在每行的结尾可能会多出一个 ^M 符号

而我们一般习惯在 windows 系统上面编写脚本编写配置文件再复制粘贴到 Linux 系统上去,如果换行符不对,就极有可能导致出错

所以我们需要将 windows 的换行符替换成 Linux 的换行符

对文件进行 sed 操作(^M 这么敲:Ctrl+v,Ctrl+m)

sed -i 's/^M//g' myfile

2.打印(p)

你可以把这个命令当成grep式的命令

涉及到打印的操作,一般与 -n 参数 搭配

如果不加参数,会是这种效果

sed '/daemon/p' test.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin

加了 -n 参数,就仅仅只把匹配到的内容输出出来

sed -n '/daemon/p' test.txt
daemon:x:2:2:daemon:/sbin:/sbin/nologin

3.删除(d)

删除匹配到的所在行

不会加 -n ,加了就什么都不输出了

1、删除 daemon 所在行

sed '/daemon/d' test.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin

2、删除 daemon 和 root 所在行

sed -e '/daemon/d' -e /root/d test.txt
bin:x:1:1:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin

4.添加(a,i)

在当前行的下一行添加

使用 a 动作

1、在文件第四行的下一行添加 newline 字符串(即添加到第五行)

sed -e '4a\newline' test.txt

sed -e '4a newline' test.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
newline
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin

在当前行的上一行添加

使用 -i 动作

1、在文件第四行的上一行添加 newline 字符串(即添加到第四行,原本第四行的内容变成了第五行)

sed -e '4i newline' test.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
newline
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin

2、在文件第一行的上一行添加 newline 字符串(即添加到第一行,原本第一行的内容变成了第二行)

sed -e '1i newline' test.txt 
newline
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
相关文章
|
6月前
|
Unix Windows Perl
sed具体的介绍
sed具体的介绍
50 2
|
Perl
Sed使用总结
Sed使用总结
43 0
|
网络协议 Perl
三剑客之 sed
三剑客之 sed
|
移动开发 开发工具 Perl
|
JavaScript Java Shell
|
JavaScript Java Shell
|
机器学习/深度学习 Unix Shell