【Linux】sed编辑器二
一、处理多行命令
sed编辑器有3种可用于处理多行文本的特殊命令。
- N:加入数据流中的下一行,创建一个多行组进行处理;
- D:删除多行组中的一行;
- P:打印多行组中的一行。
1、next命令:N
单行next命令
单行next(n)命令会告诉sed编辑器移动到数据流中的下一行,不用再返回到命令列表的最开始位置。通常sed编辑器在移动到数据流中的下一行之前,会在当前行中执行完所有定义好的命令,而单行next命令却不一样。
如下所示,文本test.txt中有两行空行。
我们想只删除第一行空行,执行下面的命令却无法做到,它会将两行空行都删除掉。
sed '/^$/d' test.txt
可以用单行next命令解决此问题:
sed '/成都/{n ; d}' test.txt # d表示删除
先用脚本查找到含有“成都”的那一行,然后,单行next命令(n)会让sed编辑器移动到文本的下一行,也就是我们想要删除的空行,接着,sed编辑器继续执行命令列表中的命令,即使用删除命令(d) 删除空行。sed编辑器在执行完命令脚本后会读取数据流中的下一行文本,并从头开始执行脚本,但它却找不到包含“成都”的行了,所以就不会再删除其它行。
合并文本行
单行next(n)命令会将数据流中的下一行移入sed编辑器的工作空间(模式空间)。多行版本的next(N)命令则是将下一行添加到模式空间中已有文本之后。这样就会将数据流中的两行文本合并到同一个模式空间中,文本行之间仍然用换行符分隔,但sed编辑器会将两行文本当成一行来处理。
模式空间(pattern space)是一块活跃的缓冲区,在sed编辑器执行命令时保存着检查的文本。
sed '/重庆/{N ; s/\n/ / }' test.txt
sed编辑器首先找到含有“重庆”的行,找到后,使用N命令将下一行与该行合并,接着使用替换命令s将换行符(\n)替换成空格。如此一来,两行文本就会成为一行后输出。
在数据文件中找到一个可能会分散在两行中的文本短语。
如下所示,电信和诈骗园区之间的 . 是用来匹配空格和换行符的,但如果它匹配到了换行符,就会删掉换行符,从而导致两行合并成一行。
可以使用两个替换命令解决上面两行合并成一行的问题。
第一个替换命令用来处理短语出现在单行中的情况,第二个替换命令用来处理短语出现在多行中的情况。
2、多行删除命令:D
sed编辑器中的多行删除命令(D)只会删除模式空间中的第一行,即删除该行中的换行符及其之间的所有字符。
删除目标数据字符串所在行的前一行。
sed '/^$/{N ; /缅北/D}' test.txt
sed编辑器首先会查找空行,然后用N命令将下一行加入模式空间,如果模式空间中有含有“缅北”的词语,那么D命令就会删除模式空间中的第一行。
3、多行打印命令:P
多行打印命令(P)只打印模式空间中的第一行,即打印模式空间中的换行符及其之前所有字符。当用-n选项来抑制脚本输出时,它就和显示文本的单行p命令的用法差不多。
如下所示,当出现多行匹配时,P命令只会打印模式空间中的第一行。此命令的强大之处在于其和N命令及D命令配合使用之时。
D命令的独特之处在于其删除模式空间中的第一行之后,会强制sed编辑器返回到脚本的起始处,对当前模式空间中的内容重新执行此命令(D命令不会从数据流中读取新行)。在脚本中加入N命令,就能单步扫过整个模式空间,对多行进行匹配。
sed -n '
N
s/#\n@//
P
D
' test.txt
整个过程是:先用sed将第一行载入模式空间,然后用N命令载入第二行(@),并将其附加到模式空间内的第一行之后。替换命令用空值替换来删除违规的数据(#\n@),然后P命令只打印模式空间中已经清理过的第一行。D命令将第一行从模式空间中删除,并返回到脚本的开头,下一个命令就将第三行文本读入模式空间,继续编辑循环。
二、保留空间
sed编辑器有另一块称作为保留空间(hold space)的缓冲区。当用户在处理模式空间中的某些行时,可以用保留空间临时保存部分行。
h | 将模式空间复制到保留空间 |
H | 将模式空间附加到保留空间 |
g | 将保留空间复制到模式空间 |
G | 将保留空间附加到模式空间 |
x | 交换模式空间和保留空间的内容 |
通常,在使用h命令或H命令将数据移入保留空间后,最终还是要用g命令、G命令或x命令将保存的数据重新移回模式空间,否则,一开始就不用考虑保存的问题。
sed -n '/缅北/{
> h ; p ;
> n ; p ;
> g ; p }
> ' test.txt
整个过程如下:
- sed使用正则表达式过滤出含有“缅北”的行;
- 当出现“缅北”的行时,{ }中的第一个命令 h 会将该行复制进保留空间。这是,模式空间和保留空间中的内容是一样的。
- p 命令会打印出模式空间的内容(缅北有电信 #1),也就是被复制进保留空间中的那一行。
- n 命令会提取数据流中的下一行(诈骗园区……),将其放入模式空间。现在,模式空间和保留空间的内容就不一样了。
- p 命令会打印出模式空间的内容(诈骗园区……)
- g 命令会将保留空间的内容(缅北有电信 #1)返回模式空间,替换模式空间中的当前文本。模式空间和保留空间的内容又相同了。
- p 命令会打印出模式空间的当前内容(诈骗园区……)
以相反的顺序输出:
sed -n '/缅北/{
> h ;
> n ; p ;
> g ; p }
> ' test.txt
三、排除命令
感叹号(!)命令用于排除(negate)命令,让原本会起作用的命令失效。
可以结合保留空间实现反转数据流中文本行的先后顺序。太复杂不过多展示。
bash shell中有 tac 命令,可以以倒序显示文本文件。
四、改变执行流程
通常来说,sed编辑器会从脚本的顶部开始,一直执行到脚本的结尾(D命令例外,它会强制sed编辑器在不读取新行的情况下返回到脚本的顶部)
1、分支命令:b
格式:[address]b [label]
- address:决定哪些行会触发分支命令
- label:定义要跳转的位置。如果没有label参数,则跳过触发分支命令的行,继续处理余下的文本行。
sed '{2,3b;
> s/line/replacement/}
> ' test.txt
分支命令跳过了第二行和第三行的替换命令,只替换了第一行和第四行。
如果不想跳到脚本末尾,可以定义label参数,指定分支命令要跳转到的位置。标签以冒号开始,最多可以有7个字符,将其放在分支命令之后。
sed '{/first/b jump1;
> s/line/replacement/
> :jump1
> s/line/Jump replacement/}
> ' test.txt
如下,分支命令指定,如果文本行中出现了first,则程序就应该跳到标签为jump1的脚本行,如果文本行不匹配分支address,则sed编辑器就会继续执行脚本中的命令,包括分支标签jump1之后的命令。因此,两个替换命令s都会被应用于不匹配分支address的行。
如果某行匹配分支address,那么sed编辑器就会跳转到带有分支标签jump1的那一行,因此只有最后一个替换命令会被执行。
如下例子演示了跳转到sed脚本下方的标签:
2、测试命令:t
测试命令也可以改变sed编辑器脚本的执行流程。它会根据先前替换命令的结果跳转到某个label处,而不是根据address进行跳转。
如果替换命令成功匹配并完成了替换,测试命令就会跳转到指定的标签。如果替换命令未能匹配指定的模式,测试命令就不会跳转。
格式:[address]t [labe1]
在没有指定label的情况下,如果测试成功,sed就会跳转到脚本结尾。
sed '{s/first/matched/ ; t
> s/line/replacement/}
> ' test.txt
第一个替换命令会先查找first,如果匹配了行中的模式,就替换文本,而且测试命令会跳过后面的替换命令。如果第一个替换未能匹配,则执行第二个替换命令。 (注意,这里说的是第二行的first替换成matched后,就不会再执行替换第二行的line了,而不是指不执行后面文本行的替换)
五、模式替换
1、&符号
&符号可以代表替换命令中的匹配模式,不管匹配到什么样的文本,都可以使用此符号代表这部分内容。
使用点号匹配at前面的那个字符,然而,用于替换的字符串“.at”无法指定点号已匹配到的字符cat和hat。
使用&符号可以解决该问题:当匹配到单词cat,“cat”就会成为替换后的单词;当匹配到单词hat,“hat”就会成为替换后的单词。
2、替换部分
&符号虽然能代表替换命令中指定模式所匹配的字符串。但有时候,用户只想获取该字符的部分。
sed编辑器使用圆括号来定义替换模式中的子模式,随后使用特殊的字符组合来引用每个子模式匹配到的文本。反向引用由反斜线和数字组成,数字表明子模式的序号,第一个子模式为\1,第二个子模式为\2,以此类推。
在替换命令中使用圆括号时,必须使用转义字符\,用此表明这不是普通的圆括号,而是用于划分子模式的。这跟转义其他特殊字符正好相反。
echo "The Guide to Programming" | sed 's/\(Guide to\) Programming/\1 DevOps/'
此命令将Guide to放入圆括号,将其标示为一个子模式,然后使用\1来提取该子模式匹配到的文本。
如果需要用一个单词替换一个短语,而此单词正好又是该短语的子串:
ehco "That furry cat is pretty." | sed 's/furry \(.at\)/\1/'
六、在脚本中使用sed
1、包装器
可以将sed编辑器命令放入shell脚本包装器,这样就不用每次使用时都重新输入整个脚本。包装器充当的是sed编辑器脚本和命令行之间的中间人角色。
#!/bin/bash
#将sed编辑器放入shell脚本包装器
#反转文件中的内容sed -n '{1!G; h; $p}' $1
exit
2、重定向sed的输出
默认情况下,sed编辑器会将shell脚本的结果输出到STDOUT。可以使用 $() 将sed编辑器命令的输出重定向到一个变量中。
#!/bin/bash
# 对sed编辑器使用shell包装器
# 计算阶乘并用逗号格式化结果factorial=1
counter=1
number=20while [ $counter -le $number ]
dofactorial=$[ $factorial * $counter ]counter=$[ $counter + 1 ]
doneresult=$(echo $factorial |
sed '{
:start
s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/
t start
}')echo "阶乘的结果是 $result"exit
七、sed实用工具
1、加倍行间距
sed 'G' test.txt
G命令只是将保留空间内容附加到模式空间内容之后,当启动sed编辑器时,保留空间只有一个空行。将它附加到已有行之后,就创建出了空行。
但是最后一行也有空行。
使用排除符号(!)和行尾符号($)确保脚本不会将空行附加到数据流的最后一行之后。
sed '$!G' test.txt
2、对可能已含有空行的文件加倍行间距
对于文本中可能已经含有空行的数据,先要将已有的空行删除,删除空行需要使用 d 命令和一个匹配空行的模式:/^$/d;然后用 G 命令在每行之后插入新的空行。
sed '/^$/d ; $!G' test.txt
3、给文件中的行编号
可以使用等号 = 显示文本中的行号
sed "=" test.txt
在获得 等号命令 的输出之后,可以通过管道符将输出传给另一个sed编辑器,由后者使用 N命令合并行号和数据行,急着使用 替换命令s 将换行符更换成空格或制表符。
sed "=" test.txt | sed 'N; s/\n/ /'
有些bash shell命令也可以查看行号
cat -n test.txtnl test.txt
4、打印末尾行
……
打印末尾的10行数据
sed '{
:start
$q ; N ; 11,$D
b start
}' test.txt
5、删除空行
删除连续的空行
删除连续空行的关键在于创建包含一个非空行和一个空行的地址区间。如果sed编辑器遇到了这个区间,它不会删除行。但对于不属于该区间的行(两个或更多的空行),则执行删除操作。
如下所示,脚本中指定的区间是/./到/^$/。区间的开始地址会匹配任何至少含有一个字符的行,区间的结束地址会匹配一个空行,在这个区间的行不会被删除。
sed '/./,/^$/!d' test.txt
删除开头的空行
如下所示,脚本用地址区间来决定要删除哪些行。这个区间从含有字符的行开始,一直到数据流结束,在这个区间内的任何行都不会从输出中删除,即含有字符的第一行之前的任何行都会被删除。
sed '/./,$!d' test.txt
删除结尾的空行
sed '{
:start
/^\n*$/{$d; N; b start }
}' test.txt
删除HTML标签
sed 's/<[^>]*>//g' test1.txt
删除多余的空行,增加 D命令:
sed 's/<[^>]*>//g ; /^$/d' test1.txt
相关文章:

【Linux】sed编辑器二
一、处理多行命令 sed编辑器有3种可用于处理多行文本的特殊命令。 N:加入数据流中的下一行,创建一个多行组进行处理;D:删除多行组中的一行;P:打印多行组中的一行。 1、next命令:N 单行next命…...

docker 部署 Kafka 单机和集群
一、准备工作 安装 Docker 确保本机已安装 Docker。可以通过以下命令检查 Docker 是否已安装:docker --version如果未安装,可以访问 Docker 官网下载并安装 Docker Desktop(Windows 和 Mac)或使用包管理器安装(Linux&…...

PHP语言的软件开发工具
PHP语言的软件开发工具 在当今数字化的时代,软件开发已经成为一种常见的职业。无论是企业级应用、网站开发还是移动应用,开发者们都需要用到各种各样的工具。PHP作为一种广泛使用的服务器端脚本语言,因其简单、灵活与强大的功能,…...

前端【3】--CSS布局,CSS实现横向布局,盒子模型
盒子分类 1、块级盒子 2、内联级盒子 3、内联块级盒子 4、弹性盒子 5、盒子内部分区 方法一:使用 float 普通盒子实现横向布局 方法二:使用 display: inline-block 内联块级元素实现横向布局 方法三:使用弹性盒子 flexbox࿰…...

SQL语句IN和OR的区别
在SQL中,IN和OR都用于筛选条件,但它们的用途和性能上有一些区别。以下是两者的对比: 1. 语法 IN SELECT * FROM table_name WHERE column_name IN (value1, value2, value3);IN用于检查某列的值是否在一个给定的值列表中。 OR SELECT * FRO…...

OCP使用中的常见问题与解决方法
OCP的常见问题 页面卡顿: 遇到页面卡顿的问题时,首先需要区分是全局性的卡顿,即所有页面都出现延迟或响应缓慢,还是仅限于特定的监控页面。 监控数据看不到: 需要明确是全部数据都无法查看,还是仅限于特定集群的数…...

Git 版本控制:.gitignore 文件完全指南
.gitignore 文件是 Git 版本控制系统中的一个重要配置文件,用于告诉 Git 哪些文件和目录应该被忽略,不需要纳入版本控制。以下是关于 .gitignore 的完整笔记。 基本概念 .gitignore 文件可以放在项目的任何目录下,其作用范围包括所在目录及…...

STM32 FreeRTOS 介绍
目录 什么是裸机开发 什么是操作系统 通用操作系统 实时操作系统 FreeRTOS简介 FreeRTOS发展历史 FreeRTOS优势 FreeRTOS特点 什么是裸机开发 裸机开发指的是在没有操作系统(OS)或者其他高级软件支持的情况下,直接在裸机硬件上进行软…...

在 Azure 100 学生订阅中新建 Ubuntu VPS 并部署 Mastodon 服务器
今天想和大家分享一下如何在 Azure 的 100 学生订阅中,创建一台 Ubuntu VPS,并通过 Docker 部署 Mastodon 服务器。Mastodon 是一个开源的社交网络平台,允许用户创建自己的实例,类似于 Twitter,但更加去中心化。Docker…...

【Linux网络编程】序列化与反序列化
目录 一,序列化和反序列化的说明 二,Jsoncpp库的介绍 三,Jsoncpp库的使用 3-1,Json::Value类 3-2,Json::StreamWriter类 3-3,Json::CharReader类 一,序列化和反序列化的说明 序列化与反…...

Spring Boot中的自动配置原理是什么
Spring Boot 自动配置原理 Spring Boot 的自动配置机制基于 条件化配置,通过 EnableAutoConfiguration 注解来启用。自动配置的核心原理是 基于类路径和环境条件来推断所需要的配置,Spring Boot 会根据项目中引入的依赖和当前环境来自动装配相关的配置项…...

大模型相关资料、基础技术和排行榜
大模型排行榜 测试集CEval中文多个学科测试集排名MMLU大规模多任务语言理解英文排名,介绍斯坦福排行榜Math-VMath-VistaOpen LLMs LeaderboardCMMLU 大模型数据集 标题简介19个大模型常用的评估数据集和训练数据集汇总19个大模型常用的评估数据集和训练数据集汇总最…...

如何安装cnpm
今天尝试用npm install安装一个项目的依赖,但是无论如何都不能完成,等待时间非常久,所以同事推荐了cnpm,确实非常好用,所以推荐了出来,希望能给大家带来帮助。 cnpm 是中国淘宝团队提供的一个 npm 镜像工具…...

正则表达式 匹配特定字符后的所有字符
在处理文本数据时,正则表达式(RegularExpressions,简称Regex)是一种非常强大的工具,它可以用来搜索、匹配和替换文本中符合特定模式的字符串。 首先,明确我们的目标是匹配完整的URL,并获取它之…...

计算机网络 (44)电子邮件
一、概述 电子邮件(Electronic Mail,简称E-mail)是因特网上最早流行的应用之一,并且至今仍然是因特网上最重要、最实用的应用之一。它利用计算机技术和互联网,实现了信息的快速、便捷传递。与传统的邮政系统相比&#…...

数据结构与算法:动态规划dp:理论基础和相关力扣题(509.斐波那契数列、70.爬楼梯)
1.0.理论基础 动态规划主要解决的问题种类有: 背包问题打家劫舍股票问题子序列问题 解决步骤: dp数组及其下标的意义递推公式dp数组初始化遍历顺序打印dp数组 2.0.相关力扣题 509.斐波那契数列 class Solution:def fib(self, n: int) -> int:i…...

某政务行业基于 SeaTunnel 探索数据集成平台的架构实践
分享嘉宾:某政务公司大数据技术经理 孟小鹏 编辑整理:白鲸开源 曾辉 导读:本篇文章将从数据集成的基础概念入手,解析数据割裂给企业带来的挑战,阐述数据集成的重要性,并对常见的集成场景与工具进行阐述&…...

word-break控制的几种容器换行行为详解
word-break 属性在控制换行行为时需要根据语言判断,对于中文 一个字符就是一个单词,字符换行不影响阅读理解,而对于英文来说,多个连续的字符才会是一个单词,例如中文的 早 英文为 morning。 morning7个字符才算一个单词…...

【0x0084】HCI_Set_Min_Encryption_Key_Size命令详解
目录 一、命令概述 二、命令格式及参数 2.1 HCI_Set_Min_Encryption_Key_Size命令格式 2.2. Min_Encryption_Key_Size 三、生成事件及参数 3.1. HCI_Command_Complete 事件 3.2. Status 四、命令的执行流程 4.1. 主机端准备阶段 4.2. 命令发送阶段 4.3. 控制器接收和…...

关于2025年智能化招聘管理系统平台发展趋势
2025年,招聘管理领域正站在变革的十字路口,全新的技术浪潮与不断变化的职场生态相互碰撞,促使招聘管理系统成为重塑企业人才战略的关键力量。智能化招聘管理系统平台在这一背景下迅速崛起,其发展趋势不仅影响企业的招聘效率与质量…...

Docker部署Spring Boot + Vue项目
目录 前提条件 概述 下载代码 打开代码 Docker创建网络 MySQL容器准备 MySQL数据库配置 启动MySQL容器 测试连接MySQL 初始化MySQL数据 Redis容器准备 修改Redis配置 启动redis容器 部署后端 后端代码打包 上传jar包到Linux 创建Dockerfile 构建镜像 运行后…...

开发规范
开发规范 企业项目开发有2种开发模式:前后台混合开发和前后台分离开发。 前后台混合开发 顾名思义就是前台后台代码混在一起开发,如下图所示: 这种开发模式有如下缺点: 沟通成本高:后台人员发现前端有问题…...

九 RK3568 android11 MPU6500
一 MPU6500 内核驱动 1.1 查询设备连接地址 查看原理图, MPU6500 I2C 连接在 I2C4 上, 且中断没有使用 i2c 探测设备地址为 0x68 1.2 驱动源码 drivers/input/sensors/gyro/mpu6500_gyro.c drivers/input/sensors/accel/mpu6500_acc.c 默认 .config 配置编译了 mpu6550 …...

openplant实时数据库(二次开发)
资源地址 我的网盘〉软件>数据库>openplant>openplant实时数据库(二次开发)...

C语言:-三子棋游戏代码:分支-循环-数组-函数集合
思路分析: 1、写菜单 2、菜单之后进入游戏的操作 3、写函数 实现游戏 3.1、初始化棋盘函数,使数组元素都为空格 3.2、打印棋盘 棋盘的大概样子 3.3、玩家出棋 3.3.1、限制玩家要下的坐标位置 3.3.2、判断玩家要下的位置是否由棋子 3.4、电脑出棋 3.4.1、…...

“AI智慧化服务系统:未来生活的智能管家
在当今快速发展的科技时代,人工智能(AI)正以前所未有的速度改变着我们的生活。AI智慧化服务系统作为这一变革的前沿技术,正在逐渐成为我们未来生活的智能管家。它们不仅提高了服务效率,还为我们带来了更加个性化和便捷…...

python管理工具:conda部署+使用
python管理工具:conda部署使用 一、安装部署 1、 下载 - 官网下载: https://repo.anaconda.com/archive/index.html - wget方式: wget -c https://repo.anaconda.com/archive/Anaconda3-2023.03-1-Linux-x86_64.sh2、 安装 在conda文件的…...

minio https配置
minio启动时候指定数据目录,配置文件,密钥文件目录,环境文件 1.创建minio用户,专门用于服务启动的 groupadd -r minio-user useradd -M -r -g minio-user minio-user 2.在当前用户目录下创建minio目录,存储minio相关文件 mkdir minio 在mini…...

SpringMVC——原理简介
狂神SSM笔记 DispatcherServlet——SpringMVC 的核心 SpringMVC 围绕DispatcherServlet设计。 DispatcherServlet的作用是将请求分发到不同的处理器(即不同的Servlet)。根据请求的url,分配到对应的Servlet接口。 当发起请求时被前置的控制…...

Ubuntu18.04 解决 libc.so.6: version `GLIBC_2.28‘ not found
Glibc(GNU C Library)是 GNU 系统及其衍生系统如 Linux 操作系统中实现 C 语言标准库的核心组件。升级 Glibc 是一个非常谨慎的操作,因为它与系统的许多关键功能和服务密切相关。Ubuntu 18.04 默认安装的 Glibc 版本为 2.27,但某些…...