0
点赞
收藏
分享

微信扫一扫

sed 进阶


contents

  • ​​多行命令​​
  • ​​next 命令​​
  • ​​单行的next命令​​
  • ​​合并文本行​​
  • ​​多行删除命令​​
  • ​​多行打印命令​​
  • ​​保持空间​​
  • ​​排除命令​​
  • ​​改变流​​
  • ​​分支​​
  • ​​测试​​
  • ​​模式替换​​
  • ​​&符号​​
  • ​​替代单独的单词​​
  • ​​在脚本中使用 sed​​
  • ​​使用包装脚本​​
  • ​​重定向 sed 的输出​​
  • ​​创建 sed 实用工具​​
  • ​​加倍行间距​​
  • ​​对可能含有空白行的文件加倍行间距​​
  • ​​给文件中的行编号​​
  • ​​打印末尾行​​
  • ​​删除行​​
  • ​​删除HTML标签​​

多行命令

在sed编辑器读取数据流时,它会基于换行符的位置将数据分成行。sed编辑器根据定义好的脚本命令一次处理一行数据,然后移到下一行重复这个过程。

如果你在文本数据中查找某个短语时,他有可能被分隔成跨行显示,如果用普通的sed编辑器命令来处理文本,就不可能发现这种被分开的短语。

sed编辑器包含了三个可用来处理多行文本的特殊命令:

  • N:将数据流中的下一行加进来创建一个多行组来处理。
  • D:删除多行组中的一行。
  • P:打印多行组中的一行。

next 命令

单行的next命令

通常sed编辑器在移动到数据流中的下一行文本前,会在当前行上执行完所有定义好的命名。而next命令,会告诉sed编辑器移动到数据流中的下一行文本,而不是重新执行命令。

sed '/header/{n ; d}' data.txt

脚本查找含有单词header的那一行,找到后,n命令会让sed编辑器移动到文本的下一行,sed编辑器会继续执行命令列表,该命令列表使用d命令来删除空白行,sed编辑器执行完命令脚本后,会从数据流中读取下一行文本,并从头开始执行命令脚本。

合并文本行

单行next命令会将数据流中的下一文本行移动到sed编辑器的工作空间。多行版本的next命令(N)会将下一文本行添加到模式空间中已有的文本后。

这样的作用是将数据流中的两个文本行合并到统一模式空间中。文本行仍然用换行符分隔,但sed编辑器现在会将两行文本当成一行来处理。

sed '/first/{ N ; s/\n/ / }' data.txt

sed 编辑器脚本查找含有单词first的那行文本,找到该行后,它会用N命令将下一行合并到那行,然后用替换命令s将换行符替换成空格。

多行删除命令

和N命令一起使用时,使用单行删除命令就要小心了。

sed 'N ; /System\nAdministrator/d' data.txt

删除命令会在不同行中查找单词System和Administrator,然后再模式空间中将两行都删掉。这未必是你想要的结果。

sed编辑器提供了多行删除命令D,它只删除模式空间中的第一行,该命令会删除到换行符(含换行符)为止的所有字符。

sed 'N ; /System\nAdministrator/D' data.txt
sed '/^$/{N ; /header/D}' data.txt

sed 编辑器脚本会查找空白行,然后用N命令来将下一文本行添加到模式空间。如果新的模式空间内容含有单词header,则D命令会删除模式空间中的第一行。如果不结合使用N命令和D命令,就不能再不删除其他空白行的情况下只删除第一个空白行。

多行打印命令

现在,你可能已经了解了单行和多行版本命令的差异,多行打印命令(P)沿用了同样的方法。它只打印多行模式空间中的第一行。这包括模式空间中直到换行符为止的所有字符。

D命令的独特之处在于强制sed编辑器返回到脚本的起始处,对同一模式空间中的内容重新执行这些命令。在命令脚本中加入N命令,你就能单步扫过整个模式空间,将多行一起匹配。

使用P命令打印出第一行,然后用D命令删除第一行并绕回到脚本的起始处。一旦返回,N命令会读取下一行文本并重新开始这个过程。这个循环会一直继续下去,直到数据流结束。

保持空间

模式空间是一块活跃的缓冲区,在sed编辑器执行命令时它会保存待检查的文本。但它并不是sed编辑器保存文本的唯一空间。

sed编辑器有另一块称作保持空间的缓冲区域,在处理模式空间中的某些行时,可以用保持空间来临时保存一些行。

保持空间命令:

命令

描述

h

将模式空间复制到保持空间

H

将模式空间附加到保持空间

g

将保持空间复制到模式空间

G

将保持空间附加到模式空间

x

交换模式空间和保持空间的内容

通常,在使用h或H命令将字符串移动到保持空间后,最终还要用g、G或x命令将保存的字符串移回模式空间。

(未完待续…)

排除命令

你可以配置命令使其不要作用到数据流中的特定地址或地址空间。
感叹号命令用来排除命令,让原本会起作用的命令不起作用。

sed -n '/header/!p' data.txt

除了包含单词header那一行外,文件中其他所有的行都被打印出来了。

(未完待续…)

改变流

通常sed编辑器会从脚本的顶部开始,一直执行到脚本的结尾(D命令是个例外,它会强制sed编辑器返回到脚本的顶部,而不读取新的行)

分支

sed 编辑器提供了一种方法,可以基于地址、地址模式或地址区间排除一整块命令。

[addres]b [label]

address 参数决定了哪些行的数据会触发分支命令。label 参数定义了要跳转到的位置,如果没有加入label参数,跳转命令会跳到脚本的结尾。

sed '{2,3b; s/This is/Is this/ ; s/line./test?/}' data.txt

分支命令在数据流中的第2行和第3行处跳过了两个替换命令。
要是不想直接跳到脚本的结尾,可以为分支命令定义一个要跳转的标签,标签以冒号开始,最多可以是7个字符长度。

(未完待续…)

测试

测试命令(t)也可以用来改变sed编辑器脚本的执行流程,测试命令会根据替换命令的结果跳转到某个标签,而不是根据地址进行跳转。

[address]t [label]

跟分支命令一样,在没有指定标签的清空下,如果测试成功,sed会跳转到脚本的结尾。如果已经做了一个替换,不需要再做另一个替换,那么测试命令能帮上忙。

sed '{
s/first/matched/
t
s/This is the/No match on/
}' data.txt

第一个替换命令会查找模式文本first,如果匹配了行中的模式,它就会替换文本,而且测试命令会跳过后面的替换命令,如果第一个替换命令未能匹配模式,第二个替换命令就会被执行。
当无需替换时,测试命令不会跳转而是继续执行剩下的脚本。

模式替换

如果你只是要匹配模式中的一个单词:

$ echo "The cat sleeps in his hat." | sed 's/cat/"cat"/'
The "cat" sleeps in his hat.

但是如果你在模式中用通配符来匹配多个单词呢?

$ echo "The cat sleeps in his hat." | sed 's/.at/"".at"/g'
The ".at" sleeps in his ".at".

用于替代的字符串无法匹配已匹配单词中的通配符字符。

&符号

&符号可以用来代替命令中匹配的模式。不管模式匹配的是什么样的文本,你都可以在替代模式中使用&符号来使用这段文本。

$ echo "The cat sleeps in his hat." | sed 's/.at/"&"/g'
The "cat" sleeps in his "hat".

当模式匹配到了单词cat,"cat"就会出现在了替换后的单词里。当它匹配了单词hat,"hat"就出现在了替换后的单词中。

替代单独的单词

在脚本中使用 sed

使用包装脚本

重定向 sed 的输出

创建 sed 实用工具

加倍行间距

对可能含有空白行的文件加倍行间距

给文件中的行编号

打印末尾行

删除行

删除HTML标签


举报

相关推荐

0 条评论