每个系统管理员必须每天处理纯文本文件。知道如何查看特定部分,如何替换单词,以及如何从那些文件过滤内容,这些都是你需要随身的技能。
我们在本文中回顾著名的流式编辑器sed,并且为了实现之前提到的目标分享使用它的15种提示。
1、查看一个文档行的范围
诸如head和tail的工具允许我们查看一个文件的顶部或底部。如果你需要查看在中间的一部分?以下sed一行将从/var/log/messages返回第5到10行:
[root@rockygu log]# sed -n '5,10p' /var/log/messages
Jul 17 04:00:13 rockygu systemd[1]: Starting system activity accounting tool...
Jul 17 04:00:13 rockygu systemd[1]: sysstat-collect.service: Succeeded.
Jul 17 04:00:13 rockygu systemd[1]: Started system activity accounting tool.
Jul 17 04:10:23 rockygu systemd[1]: Starting system activity accounting tool...
Jul 17 04:10:23 rockygu systemd[1]: sysstat-collect.service: Succeeded.
Jul 17 04:10:23 rockygu systemd[1]: Started system activity accounting tool.
2、查看除指定范围之外的整个文件
[root@rockygu log]# sed '10,$d' /var/log/messages
Jul 17 03:50:54 rockygu systemd[1]: Starting system activity accounting tool...
Jul 17 03:50:54 rockygu systemd[1]: sysstat-collect.service: Succeeded.
Jul 17 03:50:54 rockygu systemd[1]: Started system activity accounting tool.
Jul 17 03:53:01 rockygu rsyslogd[1134]: [origin software="rsyslogd" swVersion="8.2102.0-5.el8" x-pid="1134" x-info="https://www.rsyslog.com"] rsyslogd was HUPed
Jul 17 04:00:13 rockygu systemd[1]: Starting system activity accounting tool...
Jul 17 04:00:13 rockygu systemd[1]: sysstat-collect.service: Succeeded.
Jul 17 04:00:13 rockygu systemd[1]: Started system activity accounting tool.
Jul 17 04:10:23 rockygu systemd[1]: Starting system activity accounting tool...
Jul 17 04:10:23 rockygu systemd[1]: sysstat-collect.service: Succeeded.
3、查看不连续行和范围
你对不连续行的集合或者对多个范围感兴趣,让我们从/var/log/messages显示第5-7和10-13行:
[root@rockygu log]# sed -n -e '5,7p' -e '10,13p' /var/log/messages
Jul 17 04:00:13 rockygu systemd[1]: Starting system activity accounting tool...
Jul 17 04:00:13 rockygu systemd[1]: sysstat-collect.service: Succeeded.
Jul 17 04:00:13 rockygu systemd[1]: Started system activity accounting tool.
Jul 17 04:10:23 rockygu systemd[1]: Started system activity accounting tool.
Jul 17 04:20:23 rockygu systemd[1]: Starting system activity accounting tool...
Jul 17 04:20:23 rockygu systemd[1]: sysstat-collect.service: Succeeded.
Jul 17 04:20:23 rockygu systemd[1]: Started system activity accounting tool.
如你所见,-e选项允许我们为每个范围执行一个指定操作。
4、替换单词或字符(基本替代)
在/var/log/messages中用Stopping替换单词Starting的每个实例:
[root@rockygu log]# sed 's/Starting/Stopping/g' /var/log/messages
此外,为了忽略字符大小写,你会想要使用gi替代g:
[root@rockygu log]# sed 's/Starting/Stopping/gi' /var/log/messages
要用单个空白替换多个空白,我们将使用一个rocky.txt文件:
[root@rockygu blctrl]# cat rocky.txt
A B C
D E F G
[root@rockygu blctrl]# sed 's/ */ /g' rocky.txt
A B C
D E F G
5、替换在一个范围内的单词或字符
如果你只对一个行范围内替换单词感兴趣,你可以做:
[root@rockygu blctrl]# sed -n '30,40 s/Starting/Stopping/gp' /var/log/messages
Jul 17 05:30:13 rockygu systemd[1]: Stopping dnf makecache...
Jul 17 05:30:13 rockygu systemd[1]: Stopping system activity accounting tool...
你当然能够通一行的行号替换一个范围指明这一行。
6、使用正则表达式(高级替换)-I
有时装载了带有注释的配置文件。当这当然有用时,如果你想要一次查看它们,有时只显示配置指令是有帮助的。
要从/etc/fstab配置文件删除空行或者那些以#开始的行或者#号前面都是空白字符的行:
[root@rockygu blctrl]# sed '/^#\|^$\| *#/d' /etc/fstab
UUID=7347bc43-229b-4f3b-8759-2c54a6c55527 / xfs defaults 0
插入符号后跟井号(^#)表示以#号起始的行,而^$表示空行。竖线表示布尔操作,而反斜杠用于转义竖线。 *#用于表示#号前面有0个或者多个空白字符。
7、使用正则表达式(高级替代)-II
要用另一个单词替换以大写或小写开头一个单词,我们也能够使用sed。要说明,用
[root@rockygu blctrl]# cat rocky.txt
Girl girl
Women women
men
Men
Boy boy
[root@rockygu blctrl]# sed 's/[Mm]en/father/g' rocky.txt
Girl girl
Wofather wofather
father
father
Boy boy
8、查看包含指定模式的行
sed的另一种使用包括打印来自一个文件匹配指定正则表达式的行。例如,我们在CentOS 7服务器上/var/log/secure日志中查看发生在July 23下午两点的活动。
[root@rockygu blctrl]# sed -n '/Jul 19 14/p' /var/log/secure
Jul 19 14:44:03 rockygu sshd[233587]: error: kex_exchange_identification: Connection closed by remote host
9、在文件中查看空白
我们也可以使用sed在一个文件中为每个非空白行插入空白(空白行)。要在一个纯文本文件rocky.txt中每行下插入一空白行:
[root@rockygu blctrl]# cat rocky.txt
Girl girl
Women women
men
Men
Boy boy
[root@rockygu blctrl]# sed G rocky.txt
Girl girl
Women women
men
Men
Boy boy
要插入两个空白行:
[root@rockygu blctrl]# sed 'G;G' rocky.txt
Girl girl
Women women
men
Men
Boy boy
如果你想要添加多个空白行,添加一个由一个分号分隔的大写G。以下图像说明这个示例。如果你想要检查一个大型配置文件,这个提示会派上用场的。每隔一行插入一个空白行并且管道传给less将产生一个更友好的阅读习惯。
10、用行内编辑模拟dos2unix
dos2unix程序转换来自Windows/Mac格式化的纯文本文件为Unix/Linux,移除在那些平台中由某些文本编辑器插入的新行字符。如果未在你的Linux中安装它,你可以用sed模拟它的功能而不用安装它。
在下面我们看到了若干DOS新行字符(^M)
之后我们用以下移除以上这些新行字符:
[root@rockygu blctrl]# sed -i 's/\r//' test
以下是移除后的效果:
请注意-i选项表示原地编辑。接着更改将不会返回到屏幕,而是将保存在这个文件。
注意:当用vim编辑器编辑一个文件时你可以用ctrl+V和ctrl+M插入DOS新行字符。
11、原位编辑和备份原始文件
在先前提示中,我们使用sed修改一个文件但没有保存原始文件。有时,保存原始文件的一个备份复制是个好想法。
要做那件事,使用-i选项(在单引号中)并后跟一个后缀表明要重命名原始文件。
在以下示例中,我们在myfile.txt中用that替换this或This的所有实例,并且我们将保存原来的文件为myfile.txt.bak。
[root@rockygu blctrl]# ls
EPICS myfile.txt.bak Rocky rocky.sh Rocky.txt
myfile.txt rocky rocky.html rocky.txt test
[root@rockygu blctrl]# cat myfile.txt
that is the first line
that is the second line
that is the third line
that is the fourth line
that is the fifth line
that is the sixth line
[root@rockygu blctrl]# cat myfile.txt.bak
this is the first line
this is the second line
this is the third line
this is the fourth line
this is the fifth line
this is the sixth line
最终,我们将使用diff工具识别两个文件的不同:
[root@rockygu blctrl]# diff myfile.txt myfile.txt.bak
1,6c1,6
< that is the first line
< that is the second line
< that is the third line
< that is the fourth line
< that is the fifth line
< that is the sixth line
---
> this is the first line
> this is the second line
> this is the third line
> this is the fourth line
> this is the fifth line
> this is the sixth line
12、交换一对单词
假设你由一个文件,包含以名,姓格式的完整名称。你想要交换为姓和名,我们可以用sed做这件事:
[root@rockygu blctrl]# cat names.txt
Lei,Li
Meimei,Han
King,Green
[root@rockygu blctrl]# sed 's/^\(.*\),\(.*\)$/\2,\1/' names.txt
Li,Lei
Han,Meimei
Green,King
如上所见,括号和数值1和2是特殊字符,需要被转义。
1:表示每行开头到逗号之间的所有内容。
2:表示从右边第一个逗号到这行结束之间的所有内容。
13、只在找到匹配后才替换单词
有时替换指定单词的所有实例,在少数时候,不是你确切想要的。我们可能需要在找到匹配时才执行替换。
例如,我们只想要如果在相同行中找到单词services时才用stop替换start。在此种场景,这是所发生的:
[root@rockygu blctrl]# cat services.txt
We need to start partying at work,
but let's remember to start all services first.
[root@rockygu blctrl]# sed '/services/ s/start/stop/g' services.txt
We need to start partying at work,
but let's remember to stop all services first.
在第一行,start将不会被stop替换,由于单词services没有在这行上出现,而第二行中start会被stop替换掉。
14、一次执行两次或多次替换
你可以单个sed命令组合两个或更多替换。我们在myfile.txt文件中用This和verse替换单词that和line。注意:通过一个普通sed替换命令后跟一个分号和第二个替换命令来进行替换:
[root@rockygu blctrl]# sed 's/that/This/gi;s/line/verse/gi' myfile.txt
This is the first verse
This is the second verse
This is the third verse
This is the fourth verse
This is the fifth verse
This is the sixth verse
15、组合sed和其它命令
为了创建更强大命令,sed可以与其它工具组合。例如,取出所有IP地址和子网掩码:
[root@rockygu blctrl]# ifconfig | sed -n '/inet /p' | sed -e 's/[ ]*/ /' | cut -d' ' -f3,6
172.28.133.248 255.255.240.0
127.0.0.1 255.0.0.0