shell 强大工具sed

来源:互联网 发布:ucl data science 知乎 编辑:程序博客网 时间:2024/04/28 13:17

  • sed简介
  • sed工作方式
  • sed的文件查找
  • 定址
    • 文件修改
  • sed的退出码
  • sed范例
    • 打印p
    • 删除d
    • 替换命令s
    • 组合命令

sed简介

sed是一种新型的非交互的编辑工具,本质上与vi等编辑器一样提供编辑功能。与之不同的在于sed是一种非破坏的编辑工具,它不对文本进行修改,若想使修改生效,需要重定向到文本文件中。

sed工作方式

sed的工作方式如下图,sed在处理文件时,会将一行导入到模式空间(缓冲区中),在模式空间中按照我们需要的约束对其进行处理,最后根据需要输出到屏幕。因为其操作都是在模式空间中,不会对文件进行修改,因此sed是非破坏的编辑工具。
sed工作方式

sed的文件查找

sed文件查找是基于正则表达式(不明白什么是正则表达式请自行百度)

简单的例子:

sed -n '/RE/p' filenamesed -n '/goodboy/p' filename

sed [option] ‘/RE/’ filename

这个表达式由四部分组成:

  • 工具名字sed
  • 操作命令[oprtions]
  • 操作的文本’/RE/’(RE表示正则表达式)。后面会讲到,这其实是一个定址操作,即选定操作的地址。
  • 操作文件fileanme

上面的命令表示在filename文件中 匹配到goodboy行,然后打印p出来。- n表示只打印出匹配行,如果没有-n。 sed会打印出所有文本。

定址

定址就是选择编辑的部分,可以用数字和正则表达式,以及二者一起表示,如果没有给定这个范围sed将会对全文进行操作。

如果给定数字,则表示一个行号,如果用,分隔两个数字,则表示在这两行之间,$表示最后一行。

在给出定址以后,我们就可以告诉sed应该进行哪些操作了(插入,打印,删除,修改等等)
例子:

sed '1,3d' filenamesed '/[Dd]eng/p' filename 

例子中,我分别用了数字和正则表达式来定址,通常在定址之后我们需要对定址的内容进行编辑。删除或者打印等等。但是sed是非破坏性的编辑器,我们所有的更改都是在sed的模式空间中进行的,不会影响源文件。

另外,我们还可以通过!来表示一个相反的操作。比如,我们希望删除没有hello的行:

sed '/hello/!d' filename

文件修改

我们之前多次提到sed是一个非破坏性的编辑器,那么修改功能也只能通过重定向的方式来解决了

sed '/hello/d' filename > tempmv temp filename 

sed的退出码

  • 在sed语法错误的时候退出码不为0
  • 在sed执行成功(不管是否匹配成功,只要语法正确)即返回0

sed范例

打印p

p是sed打印命令,默认情况下sed打印缓冲区中的所有内容。p配合-n一起使用,可以让sed打印选定内容。
如:

#sed test data :  test.txthello print all2016/10/01
➜   sed '/hello/p' test.txt #sed test data :  test.txthello hello print all2016/10/01

sed会输出匹配行,并且打印出整个文本。

➜ sed -n '/hello/p' test.txthello 

当sed配合-n使用时,sed仅仅打印选定的行。

删除d

d命令用于删除sed的行,sed先从文件中读取文本到缓冲区,在缓冲区中进行sed操作。然后输出到屏幕上。当设置了d命令之后,该行将会在缓冲区中被删除,不会打印到屏幕上。

➜ sed '2,$d' test.txt  #sed test data :  test.txt➜ sed '1d' test.txt hello print all2016/10/01

替换命令s

sed ‘s/选择文本/替代/g’
通常选择的文本我们利用正则表达式来选定的。
末尾的g表示全局替换,如果没有选定,则表示替换每一行的第一个

➜  shell_test cat test.txt #sed test data :  test.txthello hello2hello hello2print all2016/10/01➜  shell_test sed 's/hello/seb/' test.txt #sed test data :  test.txtseb hello2seb hello2print all2016/10/01➜  shell_test sed 's/hello/seb/g' test.txt#sed test data :  test.txtseb seb2seb seb2print all2016/10/01

组合命令

通过组合上述的命令,可以完成更多,更复杂的工作。
例如我们将定址和命令放在一起,可以在选定的范围内对文本进行操作。

如:
我们在start和end之间进行一些操作

➜  shell_test cat test.txt #sed test data :  test.txthello hello2hello hello2start print all2016/10/01end➜  shell_test sed  -n '/start/,/end/p' test.txt start print all2016/10/01end

由于我们使用了正则表达式的匹配,则需要用/start/,/end/来表示选定范围,如果直接利用行号来定址则可以使用’1,3’的方式表示1行~3行(包含1行和3行)

将定址与其他操作结合:

➜  shell_test sed -n '/start/,/end/s/10/11/p' test.txt 2016/11/01
0 0