Linux 管理员 - sed 命令

sed 是一个难以掌握的复杂实用程序。此命令流式传输编辑器以过滤和转换文本。专门介绍如何熟练使用 sed 的书籍已经出版。因此请记住,本教程的目的是介绍 sed 的三个基本常见用途 −

  • 字符替换
  • 打印操作
  • 删除操作

sed 的常用命令语法是 −

sed [options] [file to operate on]

以下是需要记住的常见 sed 开关。

开关 操作
-i 在原地而不是流中编辑文件,-i[SUFFIX]创建备份文件
-e 添加要执行的脚本命令
-n 安静,禁止自动打印
-r ReGex,在脚本中使用扩展正则表达式

-i 将对文件应用更改,而不是编辑传递给 sed 的文件流。

sed-e 选项一起使用时,会扩展命令以处理流上的多个操作。这可以通过递归管道 sed 来完成。

echo "Windows and IIS run the Internet" | sed -e 's/Windows/Linux/' -e 's/ and
IIS//' -e 's/run/runs/'
Linux runs the Internet

sed-n 选项可抑制默认打印到 stdout。使用 sed 的 print 命令,如我们所见,每行都将复制到 stdout。

bash-3.2# sed 'p' ./lines.txt
line1
line1
line2
line2

这次,我们在 sed 中使用 -n 选项 −

bash-3.2# sed -n 'p' ./lines.txt  
line1 
line2

sed 将内容流发送到 stdout。添加 'p' 或 print 命令后,将为每一行发送单独的流,从而导致所有行在 stdout 中重复。

sed 替换命令

此命令使用 's' 选项指定。我们已经多次看到 sed 与其替换命令一起使用。以下是一个简单的示例 −

[root@centosLocal Documents]# echo "developers eat veggies and fruit" | sed -e
's/veggies/pizza/' -e 's/fruit/coffee/' 
developers eat pizza and coffee 
[root@centosLocal Documents]#

让我们在名为 dev.txt 的文件上尝试一下 −

[root@centosLocal centos]# cat dev.txt  
Developers code all night and sleep all day.
[root@centosLocal centos]#

现在,让我们更改文件的内容,而不仅仅是将其输出流发送到 sed

[root@centosLocal centos]# sed -ibak 's/sleep/code/' ./dev.txt  
[root@centosLocal centos]# ls dev* 
dev.txt  dev.txtbak 
[root@centosLocal centos]# cat dev* 
Developers code all night and code all day. 
Developers code all night and sleep all day. 
[root@centosLocal centos]#

注意 − 我们使用 -i 选项和一个独特的后缀来创建备份文件。

sed print 命令

此命令由 'p' 命令指定。

让我们使用 names.txt 文件,为了简洁起见,输出已被编辑 −

[root@centosLocal Documents]# sed -n "p" ./names.txt  
Ted:Daniel:101 
Jenny:Colon:608 
Dana:Maxwell:602 
Marian:Little:903 
Bobbie:Chapman:403 
Nicolas:Singleton:203 
Dale:Barton:901 
Aaron:Dennis:305

sed 允许使用"地址",以更精细地定义要打印到标准输出的内容−

[root@centosLocal Documents]# sed -n "1,10p" ./names.txt
Ted:Daniel:101 
Jenny:Colon:608 
Dana:Maxwell:602 
Marian:Little:903 
Bobbie:Chapman:403 
Nicolas:Singleton:203 
Dale:Barton:901 
Aaron:Dennis:305 
Santos:Andrews:504 
Jacqueline:Neal:102 
[root@centosLocal Documents]#

就像head一样,我们打印了 names.txt 文件的前 10 行。

如果我们只想打印出办公室在 9 楼的人员怎么办?

[root@centosLocal Documents]# sed -n "/90/p" ./names.txt 
Marian:Little:903 
Dale:Barton:901 
Kellie:Curtis:903: 
Gina:Carr:902 
Antonia:Lucas:901 
[root@centosLocal Documents]#

非常简单。我们还可以打印所有人的资料,但 9 楼办公室除外 −

[root@centosLocal Documents]# sed -n '/90/ !p' ./names.txt 
Ted:Daniel:101 
Jenny:Colon:608 
Dana:Maxwell:602 
Bobbie:Chapman:403 
Nicolas:Singleton:203 
Aaron:Dennis:305 
Santos:Andrews:504 
Jacqueline:Neal:102 
Billy:Crawford:301 
Rosa:Summers:405 
Matt:Davis:305 
Francisco:Gilbert:101
Sidney:Mac:100 
Heidi:Simmons:204 
Matt:Davis:205 
Cristina:Torres:206 
Sonya:Weaver:403 
Donald:Evans:403

在上面的代码中,我们用 ! 对 / 和 / 之间的"p"打印操作取反。这与"d"或 delete 命令的执行方式类似。但是,结果可能会因 sed 中的取反而有所不同。因此,一般规则是:p 打印并取反您不想要的内容。

sed delete 命令

如上所述,delete 命令与 sed print 命令相反。让我们从我们的 name.txt 文件 −

开始
[root@centosLocal Documents]# sed 'd' ./names.txt
[root@centosLocal Documents]#

什么都没有打印出来。使用上述命令,我们要求 sed 从 stdout 中删除流中的每一行。现在,我们只打印前两行并"删除"流的其余部分 −

[root@centosLocal Documents]# sed '1,2 !d' ./names.txt
Ted:Daniel:101
Jenny:Colon:608
[root@centosLocal Documents]#

看到了吗?类似于 'p' 或 print 命令。现在让我们使用 delete 命令做一些有用的事情。假设我们想删除文件中的所有空白行 −

[root@centosLocal Documents]# cat lines.txt  
line1 
line2 
line3 
line4 
line5 
[root@centosLocal Documents]#

收到这样的文件时,文本杂乱、复制粘贴电子邮件或使用非标准换行符格式化,这种情况并不罕见。我们可以使用 sed 代替我们完成这项工作,而不是在 vim 中交互式编辑文件。

[root@centosLocal Documents]# sed -i '/^\s*$/ d' ./lines.txt
[root@centosLocal Documents]# cat ./lines.txt
line1
line2
line3
line4
line5
[root@centosLocal Documents]#

文件现在已格式化为易于阅读的形式。

注意 − 在对重要文件进行更改时,请使用 -i 开关。强烈建议附加文件备份后缀以保留文件内容(sed 可能会因最轻微的拼写错误而做出一些极端的更改)。

basic_centos_linux_commands.html