(二十一) Sed编辑器高级部分

本文详细介绍了Sed编辑器的高级部分,包括多行命令(如next、删除和打印),保持空间与模式空间的使用,排除命令,改变流(如分支和测试),模式替代,脚本使用技巧及实用工具。重点讲解了如何处理多行文本,例如通过N命令合并文本行,D和D命令删除行,以及P命令打印特定行。此外,还介绍了保持空间与模式空间的概念,以及如何使用b和t命令进行流程控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Sed编辑器高级部分

前一篇文章 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8tgF6eS6-1593678401710)(https://blog.youkuaiyun.com/Leslie_LN/article/details/106852597)]我们介绍的所有sed编辑器命令都是针对的***一行数据***进行操作的;假如我们要匹配查找“this is leslie”短语,但如果这个短语分布在两行,用普通sed编辑器命令来处理文本就不可能成功;针对这种情况,sed编辑器包含了三个处理多行文本的特殊命令:

  1. N:将数据下一行加进来创建一个多行组来处理
  2. D:删除多行中的一行
  3. P:打印多行中的一行

1.1 多行命令

1.1.1 next命令

1.单行next命令
小写的n命令:告诉sed编辑器移动到数据流中的下一行文本

流程:

(1)、查找匹配行
(2)、移动到下一行
(3)、执行命令行列表命令

  1. 合并文本行

单行的next命令会将数据流中的下一文本行移动到模式空间;多行的next命令会将下一行添加到模式空间中已有的文本后,将数据流中两行文本合并到同一个模式空间中,文本仍然用换行符分隔,但sed编辑器现在会将两行文本当做一行文本处理;

如:

68

  1. 查找含有first的那行文本,读入模式空间
  2. N命令将下一行文本合并到first那行后面
  3. 替换命令将换行符替换为空格,文本文件中的两行在编辑器的输出中成了一行

***另外一个典型应用:***替换位于两行文字的文本短语

	on Tuesday,the Linux System
	Administrator's group meeting will be held.
	Thank you for your attendance.
	All System Administrators should attend.

这儿替换System Administrator’s,注意第一处是位于两行之间,第二处是位于最后一行;

这只是替换了跨多行的短语替换,如果单行有匹配的短语也需要替换:

69

***注意:***当N命令执行最后一行时,由于没有下一行可读了,N命令就会将编辑器停止;

这儿演示按照书上解释会出现最后一行不会匹配的,按照书上说说所有这儿应该将位于同行的替换命令移动到N命令之前,这样就不会出现上面最后一行未被正确替换的情况:

70

但是实际演示,好像并不会[P448]:
59

1.1.2 多行删除命令

单行删除命令(d):删除模式空间中的当前行;

当N和d命令一起使用时:删除的模式空间中的两行如:

多行删除命令(D):只删除模式空间中的第一行;

比如:删除文本中第一行空白行


这儿如果不和N命令使用,很难删除指定的空白行:

	sed '/^$/d' data4

删除的文本中所有空白行;

1.1.3 多行打印命令(P)

只打印多行模式空间中的第一行;

1.2 保持空间与模式空间

sed编辑器对应着两块缓冲区(保存文本),即模式空间与保持空间;

模式空间:保存带检查的文本

保存空间:保存临时文本,默认是空白行;

sed编辑器提供了五条操作模式、保持空间的命令:

	This is the header line.
	This is the first data line.
	This is the second data line.
	This is the last line.

执行:sed -n ‘/first/ {h;p;n;p;g;p}’ data4

执行步骤:

  1. 首先匹配含有first的行读入模式空间
  2. h:将模式空间内容复制到保持空间
  3. p:打印模式空间内容即第一行
  4. n:移动到第二行,读入模式空间
  5. p:打印模式空间内容即第二行
  6. g:复制保持空间内容即第一行到模式空间,此时会先清空模式空间之前的内容
  7. p:答应模式空间内容即第一行内容

1.3 排除命令(!)

放在命令前,相当于对地址取反,对特定行执行命令;

如:

	sed '/header/!p' data4

相当于除了含有header那行不打印外,其他行都打印;

1.4 改变流

1.4.1 分支(b)

格式:

[地址]b [标签]

地址:决定哪些行会触发分支命令

标签:决定可要跳转到的位置,省略这跳转到脚本末尾;以冒号开始:即(:标签名)要指定标签,将它添加到b命令后即可;

2、3行会触发分支命令,由于没有指定分支,即跳转到脚本末尾不会执行后面的连个替换命令;

如果指定标签:

用伪代码解释:

		if(2,3){

		执行标签后命令
	}else{
		执行整个命令脚本,包括标签后的命令
	}

1.4.2 测试(t)

格式:

根据替换命令结果跳转到某个标签;如果没有指定标签,

伪代码解释:

		if(替换命令匹配成功){

			跳转到指定标签
		}else{


		}

格式:

	[地址]t [标签]

1.5 模式替代

假如我们替换.at结尾的一个三个字母的单词,在匹配模式中我们可以用 .通配符来表示一个字符,但是在替代模式中无法正确匹配这个通配符,比如:可能是cat、hat…

echo "the cat sleeps in his hat" |sed 's/.at/.at/'


输出结果:	the .at sleeps in his .at

比如这里替模式的.并不是代表任意字符的特殊在字符,表示的仅仅就是“.”这个字符

sed编辑器提供了“&”符号 在替代模式中表示匹配的对应文本;如:我们我为对应文本加上双引号:

	echo "the cat sleeps in his hat"| sed 's/.at/"&"/

	输出结果:the "cat" sleeps in his hat

&提取的是对应的整个匹配文本,如果你只想替换其中一部分文本,这时就需要借助于子模式:

在匹配中()包裹要提取的一部分文本,在替换模式中 /1、/2…来提取对应文本,这里的数值1:对应第一个子模式,2对应第二个子模式,以此类推…

注意:这儿必须使用转义字符将他们标示为分组字符,而不是普通的圆括号,这跟转义其他特殊字符正相反;

	echo "this is is leslie,hello world" | sed 's/\(this\) is/\1/'


	输出:this is leslie,hello world

实例:对一个比较大的数字插入,

			echo "1112345678" | sed '{
			:start
			s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/p
			t start}'


	输出:
			1112345,678
			1112,345,678
			1,112,345,678
			1,112,345,678

1.6 在脚本中使用sed

当编辑器脚本很长时,如果 每次使用时都键入整个脚本,可想而知得多繁琐。可以将编辑器命令放到***shell包装脚本***中,包装脚本充当着编辑器脚本和命令行之间的中间角色;

在Shell脚本中可以将普通的shell变量即参数和sed编辑器脚本一起使用,比如:将命令行参数作为sed 编辑器脚本输入:

	#!/bin/bash

	sed -n '1!G;h;$p' S1


	运行Shell脚本:

	./test data4

1.6.1 重定向sed输出

默认情况,sed编辑器会将脚本的结果输出到STDOUT,在shell脚本中可以使用"$()"将sed编辑器命令输出重定向到一个变量中;

比如:

		#!/bin/bash

		result=$(echo "1112345678" | sed '{
		:start
		s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/p
		t start}')

1.7 sed使用工具

1.7.1 为文本行增加行间距

G命令:是追加保持空间内容到模式空间后面,前面我们说了,默认情况下,保持空间的为空白的即空白行;

sed '$!G' data4

我将看到相邻两行间将多出一个空白行;

1.7.2 给文本中的行编号

前面我说了借助于“=”来显示行号

78

可以看见输出行号与文本是两行显示的,借助前面学习的N命令就可实现在每行文本行前显示行号:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值