Linux的sed命令

环境

  • Ubuntu 22.04

概述

sed 是“stream editor”的意思,用来处理文本,比如做文本查找、替换。

处理单行文本

用法1

语法: sed 's/aaaa/bbbb/'

  • aaaa :用正则表达式来匹配字符串,并用圆括号括起来需要获取的内容,如 xx\(yy\)zz
  • bbbb :获取第几个圆括号里的内容,如 \1

比如,有一个由3个冒号“ : ”所分隔的字符串,比如 a:b:c:d 。想要获取第一个冒号之前的内容。

从正则表达式角度,该字符串可以看做:

.*:.*:.*:.*

分别用圆括号 () 把两个冒号之间的内容括起来,即:

(.*):(.*):(.*):(.*)

注意,圆括号需要转义,所以是:

\(.*\):\(.*\):\(.*\):\(.*\)

然后指定获取第几部分,比如第一部分就是 \1 (注意需要转义)。

完整的例子如下:

➜  ~ echo "a:b:c:d" | sed 's/\(.*\):\(.*\):\(.*\):\(.*\)/\1/'
a
➜  ~ echo "a:b:c:d" | sed 's/\(.*\):\(.*\):\(.*\):\(.*\)/\2/'
b
➜  ~ echo "a:b:c:d" | sed 's/\(.*\):\(.*\):\(.*\):\(.*\)/\3/'
c
➜  ~ echo "a:b:c:d" | sed 's/\(.*\):\(.*\):\(.*\):\(.*\)/\4/'
d

贪婪匹配

如果我们把 a:b:c:d.*:.* 来通配,即分成两部分,那么sed会怎么来划分呢?

答案:第一部分是 a:b:c ,第二部分是 d

➜  ~ echo "a:b:c:d" | sed 's/\(.*\):\(.*\)/\1/'
a:b:c
➜  ~ echo "a:b:c:d" | sed 's/\(.*\):\(.*\)/\2/'
d

这是因为,在正则表达式里, .* 是“贪婪式”的,会尽可能多的向右匹配。

所以,如果我们只想获取最后一个冒号右边的内容,并不需要把整个字符串按每个冒号划分为多个部分,而只需用 .*:.* 来通配,参见上面的例子。

sed貌似无法指定非贪婪式匹配。

如果我们想要获取第一个冒号前面的内容,可以像前面所介绍的,按照每个冒号分隔为多个部分,然后取第一部分。但是这种做法其实不太方便,比如如果字符串发生变化,多了一个冒号,那么正则表达式也得随之变化,否则就会取错内容。

一个变通的方法是:从左到右,把所有非冒号的字符( [^:]* )作为第一部分( ^ 表示“非”),后面就是 :.* ,即冒号以及随后的所有内容。

➜  ~ echo "a:b:c:d" | sed 's/\([^:]*\):.*/\1/'
a

用法2

sed还有一种用法,获取正则表达式匹配之外的内容。

语法: sed 's/aaaa//'

  • aaaa :是一个正则表达式

例如:

➜  ~ echo "abcdefg" | sed 's/cde//'
abfg

正则表达式匹配了 cde ,则获取的是前面和后面没有匹配上的内容,即 abfg

按此方法,对于 a:b:c:d ,要获取最后一个冒号右边的内容,可以简化如下:

➜  ~ echo "a:b:c:d" | sed 's/\(.*\)://'
d

若正则没有匹配成功则获取整个字符串

注意:sed的这两种用法,有一个共同的行为特点:如果正则表达式没有匹配成功,则会获取整个字符串。

比如:

➜  ~ echo "abcd" | sed 's/ab\(c\)d/\1/'
c

这是正确的匹配。如果正则没有匹配上:

➜  ~ echo "abcd" | sed 's/zzzab\(c\)d/\1/'
abcd

则获取了整个字符串。

第二种用法也同理:

➜  ~ echo "abcd" | sed 's/abc//'
d

这是正确的匹配。如果正则没有匹配上:

➜  ~ echo "abcd" | sed 's/zzzabc//'
abcd

则获取了整个字符串。

处理多行文本(比如文件)

查找内容

假设在 ~/.zshrc 里包含了 JAVA_HOME 设置:

➜  ~ grep JAVA_HOME ~/.zshrc
export JAVA_HOME=/home/ding/Downloads/jdk-17.0.3.1
export PATH=${JAVA_HOME}/bin:$PATH

现在需要通过sed获取 JAVA_HOME 的设置,即 /home/ding/Downloads/jdk-17.0.3.1

一种方法是,先通过grep命令找到那一行(假设只有一行满足条件),然后就只需处理单行文本:

➜  ~ cat ~/.zshrc | grep JAVA_HOME= | sed 's/.*JAVA_HOME=\(.*\)/\1/' 
/home/ding/Downloads/jdk-17.0.3.1

修改文件内容

比如,要把 JAVA_HOME 设置为 myPath

语法: sed -i '/aaaa/s/bbbb/cccc/'

  • aaaa :正则表达式,用来匹配行
  • s :表示替换
  • bbbb :正则表达式,表示旧内容
  • cccc :新内容

其中, -i 表示修改文件,否则只会把结果输出。

注:可以在最后加一个 g ,表示对本行做全局替换,否则只替换第一处。本例中只有一处,所以无需加 g

sed -i '/JAVA_HOME=/s/=.*/=myPath/' ~/.zshrc

本例中:

  • aaaa :为 JAVA_HOME= ,即查找符合条件的行
  • bbbb :为 =.* ,即等号以及后面所有内容
  • cccc :为目标字符串

运行后,文件内容被修改为:

......
export JAVA_HOME=myPath
......

注意:这里的 bbbb 无需匹配全部内容,而只是需被替换的内容,而前面介绍的,从字符串获取文本时,正则表达式必须要匹配全部内容。

如果目标字符串需要包含 bbbb 的内容,则可用 & 来代表。

比如,要把 export JAVA_HOME=xxxxx 改为 export JAVA_HOME=xxxxx/jdk

sed -i '/JAVA_HOME=/s/=.*/=&\/jdk/' ~/.zshrc

运行后,文件内容被修改为:

......
export JAVA_HOME==/home/ding/Downloads/jdk-17.0.3.1/jdk
......

获取一部分内容

语法: sed -n '/xxxx/,/yyyy/p'

表示输出从 xxxxyyyy 的行。其中 yyyy 可以为空,表示输出到最末。

比如,创建文件 test1.txt 如下:

abcdefg
hijklmn
opq
rst
uvw
xyz

则:

➜  ~ sed -n "/jk/,/st/p" test1.txt 
hijklmn
opq
rst
➜  ~ sed -n "/cde/,/uv/p" test1.txt
abcdefg
hijklmn
opq
rst
uvw
➜  ~ sed -n "/w/,//p" test1.txt
uvw
xyz

在一部分内容里做替换

语法: sed -i '/xxxx/,/yyyy/s/aaaa/bbbb/'

  • xxxxyyyy :开始行和结束行,也就是指定的部分内容
  • aaaa :旧内容
  • bbbb :新内容

也就是说,在 xxxxyyyy 所指定的范围内,把 aaaa 替换为 bbbb

比如, test1.txt 内容如下:

rst
abcdefg
hijklmn
opq
rst
uvw
xyz

要把所有的 rst 里的 rs 替换为 123

sed -i '/.*/s/rs/123/' test1.txt

而如果只把下方的 rst 里的 rs 替换为 123

sed -i '/pq/,/u/s/rs/123/' test1.txt

其中, pqu 划定了处理内容的范围。

分隔符

如果字符串里本身含有 / ,则匹配时,需要用 \ 来转义。

比如,要想获取字符串 /etc/ansible/hosts 里的 ansible

➜  ~ echo "/etc/ansible/hosts" | sed 's/\/etc\/\(.*\)\/hosts/\1/'
ansible

这里的正则表达式为 \/etc\/\(.*\)\/hosts ,较为复杂。

为了方便,我们可以换一个分隔符,比如换成 |

➜  ~ echo "/etc/ansible/hosts" | sed 's|/etc/\(.*\)/hosts|\1|'
ansible

这里的正则表达式为 /etc/\(.*\)/hosts ,相对简单一些。

考一考

1

求输出结果:

echo "a:b:c:d" | sed 's/\(.*\):\(.*\):\(.*\)/\1/'

答:贪婪式匹配

➜  ~ echo "a:b:c:d" | sed 's/\(.*\):\(.*\):\(.*\)/\1/'
a:b

2

求输出结果:

echo "a:b:c" | sed 's/\(.*\):\(.*\):\(.*\):\(.*\)/\1/'

答:没有匹配成功,则获取整个字符串

➜  ~ echo "a:b:c" | sed 's/\(.*\):\(.*\):\(.*\):\(.*\)/\1/'
a:b:c

3

已知字符串 {"key1":"<value1>","key2":"<value2>",......} ,从中获取 <value2> 的值( key2 是已知字符串,且 <value2> 中不含引号 " )。

答:

➜  ~ echo '{"key1":"value1","key2":"value2","key3":"value3"}' | sed 's/.*"key2":"\([^"]*\)".*/\1/'
value2

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

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

相关文章

TCPDUMP抓包明确显示IP地址和端口号

经常使用tcpdump进行抓包的同学可以忽略了&#xff0c;这篇偏于使用扫盲&#xff1b;首先&#xff0c;tcpdump抓包目的IP显示为hostname&#xff0c;如果端口是知名端口&#xff0c;显示为协议名而不是端口号。这种默认其实略有问题的&#xff1a; 如果我们使用默认的hostname…

【蓝桥杯】马的遍历

马的遍历 题目描述 有一个 n m n \times m nm 的棋盘&#xff0c;在某个点 ( x , y ) (x, y) (x,y) 上有一个马&#xff0c;要求你计算出马到达棋盘上任意一个点最少要走几步。 输入格式 输入只有一行四个整数&#xff0c;分别为 n , m , x , y n, m, x, y n,m,x,y。 …

LeetCode算法练习top100:(6)图论

package top100.图论;import java.util.LinkedList; import java.util.Queue;public class TOP {//200. 岛屿数量//网格类问题的 DFS 遍历方法int[][] ways new int[][]{{-1, 0}, {1, 0}, {0, 1}, {0, -1}};public int numIslands(char[][] grid) {int m grid.length, n gri…

目标检测——R-CNN系列检测算法总结

R-CNN系列算法详细解读文章&#xff1a; R-CNN算法解读SPPNet算法解读Fast R-CNN算法解读Faster R-CNN算法解读Mask R-CNN算法解读 目录 1、概述1.1 获取目标候选框1.2 候选框提取特征1.3 候选框分类及边框回归 2、R-CNN系列算法概述2.1 R-CNN算法2.2 SPPNet算法2.3 Fast R-CN…

2024最新版软件测试八股文(文档)

前言 &#xff08;第一个就刷掉一大批人&#xff09; 有很多“会自动化”的同学来咨询技术问题&#xff0c;他总会问到我一些元素定位的问题。元素定位其实都不算自动化面试的问题。 一般我都会问&#xff1a;你是定位不到吗&#xff1f;通常结果都是说确实定位不到。 做自…

131.类型题-计算数学序列的和,请编写函数fun,其功能是S=……【满分解题代码+详细分析】(数学序列的和类型题-C/C++JavaPython实现)

文章目录 131.类型题-计算数学序列的和:计算并输出一.题目1.1 解题思路二.解题代码2.1 C/C++解题代码2.2 python解题代码2.3 Java解题代码三.解题代码仔细分析3.1 C/C++解题代码仔细分析3.2 Java解题代码仔细分析3.3 Python解题代码仔细分析四.本类型题解题诀窍五.寄语131.类型…

Spring Boot 之 ModelFactory

1.initModel 功能&#xff1a; public void initModel(NativeWebRequest request, ModelAndViewContainer container, HandlerMethod handlerMethod)throws Exception {Map<String, ?> sessionAttributes this.sessionAttributesHandler.retrieveAttributes(request);c…

Codeforces Round 910 (Div. 2)

Codeforces Round 910 (Div. 2) 文章目录 Codeforces Round 910 (Div. 2)ABCD A 模拟 #include <bits/stdc.h>using namespace std; const int N1e510; char s[N];void solve(){int n , k , cb 0 , ans 0;cin >> n >> k;for(int i 1 ; i < n ; i ){c…

简易电路特性测试仪

目录 摘 要... 3 第一章 绪论... 5 1.1 研究课题背景... 5 1.2 国内外发展概况... 7 1.3 课题研究的目的... 9 1.4 课题的研究内容及章节安排... 9 第二章 电路特性测试仪的设计方案... 10 2.1 系统总体设计思路... 10 2.2 电路特性测试仪总体设计方案…

HarmonyOS开发上手

首先献出开发官网地址 &#xff08;https://developer.harmonyos.com/cn/develop/&#xff09; 本文内容 基础入门内容介绍安装DevEco StudioDevEco Studio常用功能介绍项目工程结构详解 1. 基础入门内容介绍 应用开发流程 在正式开始之前还需要了解一些有关的基础概念 方舟…

【PyTorch】概述

文章目录 1. PyTorch是什么&#xff1f;2. PyTorch的特点3. PyTorch的架构 1. PyTorch是什么&#xff1f; PyTorch是一个深度学习框架&#xff0c;由Facebook于2016年开源发布。PyTorch是基于Torch框架的Python接口&#xff0c;旨在提供易用的强大工具来进行神经网络的构建和训…

python实现从远程服务器读取 JSON 文件、解析内容并将其存储到 MySQL 表中,然后删除已解析的文件

创建一个 Python 脚本&#xff0c;利用 Paramiko 库连接到远程服务器&#xff0c;读取 JSON 文件、解析内容并将其存储到 MySQL 表中&#xff0c;最后删除文件。 import paramiko import json import MySQLdb import os# SSH 连接参数 ssh_client paramiko.SSHClient() ssh_c…

H5流媒体播放器EasyPlayer播放H.265新增倍速播放功能,具体如何实现?

目前我们TSINGSEE青犀视频所有的视频监控平台&#xff0c;集成的都是EasyPlayer.js版播放器&#xff0c;它属于一款高效、精炼、稳定且免费的流媒体播放器&#xff0c;可支持多种流媒体协议播放&#xff0c;包括WebSocket-FLV、HTTP-FLV&#xff0c;HLS&#xff08;m3u8&#x…

做项目碰到的一些安卓与苹果的不兼容,做个记录

默认字体 // 苹果手机默认字体为 font-family:simsun; // 安卓和H5默认字体为 font-family: initial;屏幕截图(html-to-image) // 这里只做js部分(vue3使用)import * as htmlToImage from html-to-image;let imgcanvas ref() // 图片标签img的src指向const captureScreen ()…

vivado分析-在 Versal 器件中执行 NoC 服务质量分析

AMD Vivado ™ 中的服务质量 (QoS) 用于将片上网络 (NoC) 编译器生成的当前 NoC 解决方案估算所得 QoS 与 AXI NoCIP 和 / 或 AXI4 ‑ Stream NoC IP 中指定的 QoS 要求进行对比。一旦 NoC 解决方案过时 &#xff0c; 就需要调用 NoC 编译器并生成新的 NoC 解决方案以…

论文投稿查询会议期刊及deadlines的网站

1. 这个是查近期CCF-ABC的ddl会议的网址 https://ccfddl.github.io/ https://ccfddl.top/ 2. 期刊选刊 https://ijournal.topeditsci.com/home https://journalsuggester.springer.com/ 3. IEEE出版物推荐 https://publication-recommender.ieee.org/home

微信小程序跳转到外部小程序

要在微信小程序中跳转到外部小程序&#xff0c;你可以使用 navigateToMiniProgram 或 redirectToMiniProgram API。下面是它们的说明和代码示例&#xff1a; navigateToMiniProgram API&#xff1a; 该 API 可以让用户从当前小程序跳转到另一个外部小程序&#xff0c;并保留当…

《算法通关村——滑动窗口高频问题之**寻找子串异位词**》

《算法通关村——滑动窗口高频问题之寻找子串异位词》 567. 字符串的排列 给你两个字符串 s1 和 s2 &#xff0c;写一个函数来判断 s2 是否包含 s1 的排列。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 换句话说&#xff0c;s1 的排列之一是 s2…

python3实现定时拉取rabbitmq队列里面的数据,并输出到文件中。

使用pika,一个Python RabbitMQ客户端库&#xff0c;结合Python的datetime和json库来实现定时从RabbitMQ队列中拉取数据&#xff0c;并将数据输出到按当天日期动态生成的文件中。 首先&#xff0c;确保您已经安装了 pika 库。如果尚未安装&#xff0c;可以使用以下命令进行安装&…

重温经典struts1之搭建环境

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 前言 今天参加了一个项目&#xff0c;什么项目&#xff1f;struts1的项目&#xff0c;什么&#xff1f;&#xff01;现在还有struts1的项目&#xff0c;读到这里你是不是和我…