【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

 整个过程如下:

  1. sed使用正则表达式过滤出含有“缅北”的行;
  2. 当出现“缅北”的行时,{ }中的第一个命令 h 会将该行复制进保留空间。这是,模式空间和保留空间中的内容是一样的。
  3. p 命令会打印出模式空间的内容(缅北有电信 #1),也就是被复制进保留空间中的那一行。
  4. n 命令会提取数据流中的下一行(诈骗园区……),将其放入模式空间。现在,模式空间和保留空间的内容就不一样了。
  5. p 命令会打印出模式空间的内容(诈骗园区……)
  6. g 命令会将保留空间的内容(缅北有电信 #1)返回模式空间,替换模式空间中的当前文本。模式空间和保留空间的内容又相同了。
  7. 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=20

while [ $counter -le $number ]
do
  factorial=$[ $factorial * $counter ]
  counter=$[ $counter + 1 ]
done

result=$(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.txt

nl 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/955028.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

从AI生成内容到虚拟现实:娱乐体验的新边界

引言 在快速发展的科技时代&#xff0c;娱乐行业正经历一场前所未有的变革。传统的娱乐方式正与先进技术融合&#xff0c;创造出全新的沉浸式体验。从AI生成的个性化内容&#xff0c;到虚拟现实带来的身临其境的互动场景&#xff0c;科技不仅改变了我们消费娱乐的方式&#xf…

下载文件,浏览器阻止不安全下载

背景&#xff1a; 在项目开发中&#xff0c;遇到需要下载文件的情况&#xff0c;文件类型可能是图片、excell表、pdf、zip等文件类型&#xff0c;但浏览器会阻止不安全的下载链接。 效果展示&#xff1a; 下载文件的两种方式&#xff1a; 一、根据接口的相对url&#xff0c;拼…

springMVC---常用注解

目录 一、创建项目 1.依赖 2.web.xml 3.spring-mvc.xml 二、RequestParam注解 1.作用 2.属性 3.代码 DeptController类 启动tomcat 三、RequestBody注解 1.作用 2.属性 3.代码 (1&#xff09;DeptController类 (2&#xff09;index.jsp (3)启动tomcat 四、P…

记录一次微信小程序使用云能力开发的过程

对于开发微信小程序云开发不知从何起的同学们&#xff0c;可以当作一次参考。虽说官方有文档&#xff0c;有模板示例&#xff0c;但是这些都是片段或者完整的结果展示。对于初学或者开发经验较少的同学们&#xff0c;可能不知先从那里入手进行第一步的开发。下面解析下构建微信…

Agent一键安装,快速上手Zabbix监控!

目录 一、Linux操作系统部署Agent环境配置1、防火墙配置2、永久关闭selinux yum方式安装1、配置zabbix仓库2、安装agent3、配置 Zabbix-Agent 指向 Zabbix-Server4、启动agent服务 二进制包安装1、下载二进制包2、创建用户和目录及更改属主&#xff08;组&#xff09;3、解压二…

人工智能实验(五)-基于神经网络的模式识别实验

一、实验目的 理解BP神经网络的结构和原理&#xff0c;掌握反向传播算法对神经元的训练过程&#xff0c;了解反向传播公式。通过构建BP网络模式识别实例&#xff0c;熟悉BP网络的原理及结构 二、实验内容 基于提供的数据集&#xff0c;训练1个BP神经网络模型&#xff1a; 1. …

开发手札:.asmdef和RuntimeInitializeOnLoadMethod

最近为了快速响应临时小demo和老项目改造开发&#xff0c;思考了几种方式。 一般我们开发都是基于一套完善的unity框架进行的&#xff0c;完全建一个new project就是干&#xff0c;这样开发不仅慢而且乱。我们组框架代码都有现成的&#xff0c;而且组员都熟练使用了&…

九 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 …

Quinlan C4.5剪枝U(0,6)U(1,16)等置信上限如何计算?

之前看到Quinlan中关于C4.5决策树算法剪枝环节中,关于错误率e置信区间估计,为啥 当E=0时,U(0,1)=0.75,U(0,6)=0.206,U(0,9)=0.143? 而当E不为0时,比如U(1,16)=0.157,如图: 关于C4.5决策树,Quinlan写了一本书,如下: J. Ross Quinlan (Auth.) - C4.5. Programs f…

机器学习第一道菜(一):线性回归的理论模型

机器学习第一道菜&#xff08;一&#xff09;&#xff1a;线性回归的理论模型 一、问题&#xff1a;千金买笑1.1 散点图1.2 机器学习能搞啥 二、模型的建立2.1 线性回归2.2 回归模型 前面讲了机器学习的“四大绝技”&#xff0c;今天&#xff0c;开始研究第一绝技“回归”&…

Edge Scdn是什么,它如何提升网站安全性与访问速度?

随着网络攻击的日益猖獗&#xff0c;尤其是分布式拒绝服务&#xff08;DDoS&#xff09;攻击的频繁发生&#xff0c;如何保护网站的安全性并确保用户的访问体验变得极为重要。Edge Scdn&#xff08;内容分发网络&#xff09;作为一种新兴的技术方案&#xff0c;逐渐被越来越多的…

深入浅出Redis持久化

文章目录 前言RDB快照原理保存时机 AOF同步策略AOF重写 混合持久化总结 前言 redis作为内存数据库&#xff0c;数据都在内存里&#xff0c;如果突然宕机&#xff0c;则数据都会丢失&#xff08;这里假设不使用非易失性内存&#xff09;&#xff0c;redis提供了持久化机制来防止…

JAVA实现五子棋小游戏(附源码)

文章目录 一、设计来源捡金币闯关小游戏讲解1.1 主界面1.2 黑棋胜利界面1.3 白棋胜利界面 二、效果和源码2.1 动态效果2.2 源代码 源码下载更多优质源码分享 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/article/details/145161039 JA…

无公网IP 实现外网访问本地 Docker 部署 Navidrome

Navidrome 是一款可以在 macOS、Linux、Windows以及 Docker 等平台上运行的跨平台开源音乐服务器应用&#xff0c;它支持传输常见的 MP3、FLAC、WAV等音频格式。允许用户通过 Web 界面或 API 进行音乐库的管理和访问。本文就介绍如何快速在 Linux 系统使用 Docker 进行本地部署…

JS后盾人--JS数组挖掘(少年篇)

数组引用类型分析 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> </he…

VirtualBox环境中vscode报错:提取扩展时出错。Failed to fetch

问题现象&#xff1a; VSCode切换到扩展并筛选特色时(为了触发联网)&#xff0c;提示提取扩展时出错。Failed to fetch 拔网线复现不了&#xff0c;完全没有网络VSCode只会提示离线 虚拟机内Edge浏览器访问https://marketplace.visualstudio.com/直接报ERR_CONNECTION_REFUSED…

HTML文章翻页功能

效果展示&#xff1a; 效果原理&#xff1a; 1、引入CDN 2、绘制文章翻页样式&#xff0c;以及自动分段 3、获取窗口宽高&#xff0c;计算出当前文章总分段&#xff0c;并实现分页 4、完整代码 <!DOCTYPE html> <html><head><meta charset"utf-8&qu…

IDEA运行测试函数@Test注解旁边没有运行按钮

如图我想直接运行 testSaveShop 函数进行测试&#xff0c;但是旁边没有运行按钮。 解决办法&#xff1a;测试类需要加上public&#xff0c;系统才能识别到并调用运行。 位置如下&#xff0c;在类和方法都加上 public &#xff0c;然后就会出现运行按钮&#xff1a; 但是如果点…

计算机网络 (38)TCP的拥塞控制

前言 TCP拥塞控制是传输控制协议&#xff08;Transmission Control Protocol&#xff0c;TCP&#xff09;避免网络拥塞的算法&#xff0c;是互联网上主要的一个拥塞控制措施。 一、目的 TCP拥塞控制的主要目的是防止过多的数据注入到网络中&#xff0c;使网络能够承受现有的网络…

使用jupyter notebook没有正常打开浏览器的几种情况解决

迅速记录前期 1.下载 https://www.anaconda.com/products/individual 2.安装 直接默认安装就行 3.打开jupyter notebook 在开始菜单里面可以找到 4.遇到的问题解决 1.运行jupyter notebook&#xff0c;黑窗口自动关了 每次黑窗口迅速的加载完就自己关掉了 也没有打开新…