每个系统管理员必须每天处理纯文本文件。知道如何查看特定部分,如何替换单词,以及如何从那些文件过滤内容,这些都是你需要随身的技能。
我们在本文中回顾著名的流式编辑器sed,并且为了实现之前提到的目标分享使用它的15种提示。
诸如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.
- [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.
你对不连续行的集合或者对多个范围感兴趣,让我们从/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选项允许我们为每个范围执行一个指定操作。
在/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
如果你只对一个行范围内替换单词感兴趣,你可以做:
- [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...
你当然能够通一行的行号替换一个范围指明这一行。
有时装载了带有注释的配置文件。当这当然有用时,如果你想要一次查看它们,有时只显示配置指令是有帮助的。
要从/etc/fstab配置文件删除空行或者那些以#开始的行或者#号前面都是空白字符的行:
- [root@rockygu blctrl]# sed '/^#\|^$\| *#/d' /etc/fstab
- UUID=7347bc43-229b-4f3b-8759-2c54a6c55527 / xfs defaults 0
插入符号后跟井号(^#)表示以#号起始的行,而^$表示空行。竖线表示布尔操作,而反斜杠用于转义竖线。 *#用于表示#号前面有0个或者多个空白字符。
要用另一个单词替换以大写或小写开头一个单词,我们也能够使用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
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
我们也可以使用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将产生一个更友好的阅读习惯。
dos2unix程序转换来自Windows/Mac格式化的纯文本文件为Unix/Linux,移除在那些平台中由某些文本编辑器插入的新行字符。如果未在你的Linux中安装它,你可以用sed模拟它的功能而不用安装它。
在下面我们看到了若干DOS新行字符(^M)
之后我们用以下移除以上这些新行字符:
[root@rockygu blctrl]# sed -i 's/\r//' test
以下是移除后的效果:
请注意-i选项表示原地编辑。接着更改将不会返回到屏幕,而是将保存在这个文件。
注意:当用vim编辑器编辑一个文件时你可以用ctrl+V和ctrl+M插入DOS新行字符。
在先前提示中,我们使用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
假设你由一个文件,包含以名,姓格式的完整名称。你想要交换为姓和名,我们可以用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:表示从右边第一个逗号到这行结束之间的所有内容。
有时替换指定单词的所有实例,在少数时候,不是你确切想要的。我们可能需要在找到匹配时才执行替换。
例如,我们只想要如果在相同行中找到单词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替换掉。
你可以单个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
为了创建更强大命令,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