2024年2月19日 - mis

当需要在两个或多个子模式间插入文本时,这个特性尤其有用。这里有个脚本,它使用子模式在大数字中插入逗号。

$ echo "1234567" | sed '{
> :start
> s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/
> t start
> }'
1,234,567
$

​ 这个脚本将匹配模式分成了两部分。
​ .*[0-9]
​ [0-9]{3}
​ 这个模式会查找两个子模式。第一个子模式是以数字结尾的任意长度的字符。第二个子模式
是若干组三位数字(关于如何在正则表达式中使用花括号的内容可参考第20章)。如果这个模式
在文本中找到了,替代文本会在两个子模式之间加一个逗号,每个子模式都会通过其位置来标示。
这个脚本使用测试命令来遍历这个数字,直到放置好所有的逗号。

正则表达式中的子模式“.*[0-9]”表示匹配任意长度的字符,以数字结尾。这是因为:

  1. 点号(.):在正则表达式中,点号(.)是一个特殊字符,它匹配除了换行符之外的任何单个字符。
  2. 星号(*):星号(*)是一个量词,表示前面的字符可以出现零次或多次。当它跟在点号后面时,就表示匹配任意长度的字符序列。注意:这里的星号会尽可能的多匹配字符。
  3. 字符集[0-9]:方括号内的范围表示一个字符集,匹配任何一个指定的字符。在这里,[0-9]表示匹配任何一个数字字符。

[0-9]{3} 是一个正则表达式的子模式,它匹配的是恰好由三个数字组成的字符串

  1. 字符集[0-9]:在正则表达式中,方括号[]用来定义一个字符集合,匹配任何一个指定的字符。这里的[0-9]表示匹配从0到9之间的任何一个单个数字字符。
  2. 量词{3}:花括号{}中的3是一个量词,表示前面的字符集[0-9]必须连续出现3次。

疑惑:循环两次的匹配,它到底应该先匹配哪个比较好,我的意思是可以有很多种情况,例如:第一次循环的时候可以是 1,234567 或 1234,567 或 12,34567 等等;所以要循环一次才可以看出来:

bobo@thj:~/Havefun$ echo "1234567" | sed '{
> s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/
> }'
1234,567
bobo@thj:~/Havefun$ echo "1234567f" | sed '{
s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/
}'
1234,567f
bobo@thj:~/Havefun$ echo "1234567f123" | sed '{
s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/
}'
1234,567f123
bobo@thj:~/Havefun$ echo "1234,567f123" | sed '{
s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/
}'
1,234,567f123

总结:他是从后面向前面匹配的,先找到最后连续的3个数字,然后向前找一位。感觉上像是在尽力照顾全局。(为什么要这样设计呢?)这是因为在正则表达式中,.*[0-9] 这部分会尽可能多地匹配字符,直到最后一个数字。

可是 为什么*要尽可能多匹配字符,而不是尽可能少的匹配字符呢? (然后发现还有贪婪匹配和非贪婪匹配这种东西😂)

​ 正则表达式中的 * 量词默认是贪婪的,这意味着它会尽可能多地匹配字符。这种设计的原因主要是为了提供一种默认的行为,使得在大多数情况下能够满足匹配的需求。贪婪匹配是一种最大化匹配策略,它尝试找到最长的可能匹配,这样可以确保表达式能够匹配到所有可能的情况。

然而,有时候我们可能需要最小化匹配,即匹配尽可能少的字符。在这种情况下,可以使用非贪婪匹配,通常是通过在量词后面加上一个问号 ? 来实现,如 *?+??? 等。这样,正则表达式引擎会在找到第一个可能的匹配后停止,不再继续寻找更长的匹配。


  • 命令n:小写的n是next命令的简写。这个命令会告诉sed编辑器移动到输入数据流中的下一行,而不用重新执行当前行上的所有命令。通常sed会在处理当前行之前的所有命令后,再移动到下一行。但使用n命令可以改变这一流程,使得sed在处理完当前行上的某个特定命令后即刻移动到下一行。
  • 命令N:大写的N用来将输入数据流中的下一行加到当前行之后,创建一个多行组。这对于处理跨多行的文本操作非常有用。当N命令执行后,它们会被视为一个整体来处理接下来的sed命令。

bobo@thj:~/Havefun$ nl data2.txt1  This is the header line.2  This is the first data line.3  This is the second data line.4  This is the last line.
bobo@thj:~/Havefun$
bobo@thj:~/Havefun$
bobo@thj:~/Havefun$ cat -n data2.txt1  This is the header line.2  This is the first data line.3  This is the second data line.4  This is the last line.
bobo@thj:~/Havefun$

bash shell 命令也可以添加行号,但是会有间隔。


那么,如何用美元符来显示数据流末尾的若干行呢?答案是创建滚动窗口。
滚动窗口是检验模式空间中文本行块的常用方法,它使用N命令将这些块合并起来。N命令将
下一行文本附加到模式空间中已有文本行后面。一旦你在模式空间有了一个10行的文本块,你可
以用美元符来检查你是否已经处于数据流的尾部。如果不在,就继续向模式空间增加行,同时删
除原来的行(记住,D命令会删除模式空间的第一行)。

通过循环N命令和D命令,你在向模式空间的文本行块增加新行的同时也删除了旧行。分支命
令非常适合这个循环。要结束循环,只要识别出最后一行并用q命令退出就可以了。

$ cat data7.txt
This is line 1.
This is line 2.
This is line 3.
This is line 4.
This is line 5.
This is line 6.
This is line 7.
This is line 8.
This is line 9.
This is line 10.
This is line 11.
This is line 12.
This is line 13.
This is line 14.
This is line 15.
$
$ sed '{
> :start
> $q ; N ; 11,$D
> b start
> }' data7.txt
This is line 6.
This is line 7.
This is line 8.
This is line 9.
This is line 10.
This is line 11.
This is line 12.
This is line 13.
This is line 14.
This is line 15.

如果是最后一行的话就退出,然后将下一行添加到模式空间中去,接着继续执行下面的命令,然后检查这一行是不是11行到最后一行,如果是的话,就删除模式空间的第一行;如此循环处理每一行,因为一共是15行,所以会删除前面5行。


$ cat data8.txt
This is line one.This is line two.This is line three.This is line four.
$
$ sed '/./,/^$/!d' data8.txt
This is line one.This is line two.This is line three.This is line four.
$

,:表示范围操作符,这里指从匹配第一个模式的行开始到匹配第二个模式的行结束,期间的所有行都将作为一组处理。区间是/./到/^$/。区间的开始地址会匹配任何含有至少一个字符的行。区间的结束地址会匹配一个空行。在这个区间内的行不会被删除。(为什么最后一行就不会删除呢,逆天!!!)


$ cat data10.txt
This is the first line.
This is the second line.$ sed '{
> :start
> /^\n*$/{$d ; N ; b start }
> }' data10.txt
This is the first line.
This is the second line.
$

这就删除了最后两行了,大写的疑惑?

我们来分析一下,将删除命令改为打印命令,看看是如何循环的:

bobo@thj:~/Havefun$ cat data10.txt | sed '=' | sed 'N; s/\n/ /'
1 This is the first line.
2 This is the second line.
3
4
5
bobo@thj:~/Havefun$ sed '{
:start
/^\n*$/{$p ; N ; b start }
}' data10.txt | sed '=' | sed 'N; s/\n/ /'
1 This is the first line.
2 This is the second line.
3
4
5
6
7
8
bobo@thj:~/Havefun$

首先注意一个问题:sed 编辑器默认情况下并不支持模糊匹配,它采用的是正则表达式进行精确或基于模式的匹配操作

先看前两行,没有被p 命令打印,说明不满足匹配条件;但是我感觉后面三行是整体打印的。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue3项目引入本地js文件,实现一个音频播放按钮

目前有一个需求就是在网页上放置一个音乐控制按钮,并且是在vue3项目里面。于是小白的我遇到了2个问题,第一个问题是如何实现没有进度条的播放按钮,这个网上有现成的代码,可以通过js代码切换不同的图片或者是别的样式,并…

SpringBoot-将Bean放入容器的五种方式

1、Configuration Bean Configuration public class MyConfiguration {Beanpublic Person person() {Person person new Person();person.setName("spring");return person;} } 2、Componet ComponentScan Component public class Person {private String name;pu…

SparkSQL学习02-编程入口

文章目录 1 DataFrame的构建方式方式一:JavaBean反射的方式1.1 创建Scala类1.2 创建Scala对象 方式二:动态编码的方式 2 DataSet的构建方式3 RDD和DataFrame以及DataSet之间的相互转换3.1【RDD-->DataFrame】和【RDD-->DataSet】3.2【DataFrame--&…

java基础之 SPI机制

SPI机制说明 什么是SPI Service Provider Interface 机制是Java提供的一套用来被第三方实现或扩展的API,他可以用来启用框架扩展和替换组件。通过“基于接口的编程 策略模式 配置文件”组合实现的动态加载机制。SPI机制为某个接口寻找服务实现的机制,…

二叉树基础知识总结

目录 二叉树基础知识 概念 : 根节点的五个形态 : 特殊的二叉树 满二叉树 : 完全二叉树 : 二叉搜索树 : 平衡二叉搜索树 : 二叉树的性质 : 二叉树的存储结构 二叉树的顺序存储结构 二叉树的链式存储结构 二叉树的遍历方式 : 基础概念 前中后遍历 层序遍历 :…

【Redis】理论进阶篇------浅谈Redis的缓存穿透和雪崩原理

一、缓存穿透 1、概念 缓存穿透(查不到数据),是指当用户想要查询数据的时候,会先去Redis中取命中,如果Redis中没有该数据,那么就会向数据库中去查找数据。如果数据库中也没有,则该次查询结果失…

Hive 最全面试题及答案(基础篇)

基本知识 hive元数据存储 Hive 元数据存储了关于表、分区、列、分桶等信息。 在生产环境中,通常会将 Hive 的元数据存储在外部的关系型数据库中,如 MySQL 或 PostgreSQL。这样可以提供更好的性能、可扩展性和容错性。通过配置 Hive 的元数据存储为 MySQL 或 PostgreSQL,可以…

Spring学习笔记(五)--Spring的AOP模块

一、AOP的底层原理 AOP的底层原理是动态代理,动态代理有两种方式:JDK动态代理和CGLib动态代理,在有接口的实现类时我们通常用JDK的动态代理方式(默认情况)为类创建代理对象,JDK的动态代理方式可以实现无入…

ORM中常用的字段和参数,正反向概念

django表查询测试环境搭建 首先,在此之前我们先来回顾一下之前学习的orm内容 1. django自带一个小型的sqlite3的小型数据库 但是这个数据库的功能非常有限,并且针对日期类型的数据兼容性很差 2. 切换数据库数据(MySQL) 2.1 在django1.x版本中你需要在_…

Android TextView.setText() 引发的卡顿问题

在 Android 开发中,TextView 是一个非常基础和常用的用户界面组件,用于在屏幕上显示文本内容。TextView 继承自 View 类,并提供了展示文本以及相关样式处理的功能。 TextView 允许开发者在应用程序的用户界面中显示格式化的文本内容。它支持…

PotPlayer+Alist挂载并播放网盘视频

文章目录 说明技术WebDAVPotPlayer 操作步骤一:Alist开启WebDAV代理二:PotPlayer连接Alist 说明 Alist网页端播放视频受限,主要是文件大于20MB,由于官方限制,无法播放需要使用user-agent修改插件,设置百度…

html中如何给input输入框这个一个默认值

在HTML中&#xff0c;要给<input>输入框设置一个默认值&#xff0c;你可以使用value属性。下面是一个简单的例子&#xff0c;展示了如何为一个文本输入框设置一个默认值&#xff1a; <input type"text" value"这是默认值">在这个例子中&#…

《最新出炉》系列初窥篇-Python+Playwright自动化测试-24-处理单选和多选按钮-上篇

1.简介 在工作和生活中&#xff0c;经常会遇到我们需要进行选择的情况&#xff0c;比如勾选我们选择性别&#xff0c;男女两个性别总是不能同时选中的&#xff0c;再比如我们在选择兴趣爱好时&#xff0c;我们可以选择多个自己感兴趣的话题&#xff0c;比如&#xff1a;篮球、…

sqllabs第46关 order by 注入

简介&#xff1a;&#xff08;order by注入-错误回显-POST注入&#xff09; 请求方法&#xff1a;POST 方法&#xff1a;order by注入错误回显数字型注入 先了解下 order by参数注入&#xff1a; order by 注入是指其后面的参数是可控的&#xff0c; order by 不同于我们在 whe…

gem5学习(23):经典缓存——Classic Caches

目录 一、Interconnects 1、Crossbars 二、Debugging 官网教程&#xff1a;gem5: Classic caches 默认缓存是一个带有MSHR&#xff08;未命中状态保持寄存器&#xff09;和WB&#xff08;写缓冲区&#xff09;的非阻塞缓存&#xff0c;用于读取和写入未命中。缓存还可以启用…

6.3 存储卡

本节介绍Android的文件存储方式--在存储卡上读写文件&#xff0c;包括&#xff1a;公有存储空间与私有存储空间有什么区别&#xff0c;如何利用存储卡读写文本文件&#xff0c;如何利用存储卡读写图片文件&#xff0c;如何在App运行的时候动态申请权限等。 6.3.1 私有存储空间…

Android应用图标防止被系统缩放问题

问题 Launcher显示应用的图标时可能有一定程度的缩放和剪裁后剧中&#xff0c;可能导致我们应用的图标看起来过小。 解决方法 在icon资源中用xml去放置资源ic_launcher.xml&#xff0c;不要直接使用png&#xff0c;然后把自己的资源放在xml中的foreground 标签中。 <appli…

关于Linux搭建DedeCMS说明

使用环境 1. Ubuntu 22.042. PhP 4.0 3. nginx4. MySQL 5.7软件安装 安装nginx #1. 更新系统 sudo apt update && sudo apt upgrade -y#2. 安装nginx sudo apt install nginx -y安装MySQL apt list -a mysql-server安装 PHP 7.4 使用 ondrej/php PPA sudo apt inst…

[java基础揉碎]this

引出this: 什么是this: java虚拟机会给每个对象分配 this&#xff0c;代表当前对象。 这里的this就是new出来的这个对象 this的本质: this是个引用在堆中指向它自己: this的细节: 访问成员方法: 访问构造器:

精英ECS Z97-MACHINE V1.0 BIOS MX25L6406E

官网上的两个BIOS我都无法亮机&#xff0c;这是我保存出来的BIOS&#xff0c;不知道是否能使用五代的处理器 官网&#xff1a;Z97-MACHINE&#xff5c;Motherboard&#xff5c;产品&#xff5c;ECS 精英电脑 国外老哥的看法&#xff1a;ECS Z97-MACHINE Closer Look: The BIO…