Linux sed命令详解-结构(清楚结构便于理解记忆)-选项-模式空间与暂存区(多示例、多图)

文章目录

  • sed基本结构
  • 选项
    • -n(静默模式)
    • -e、;(多点编辑,多条命令)
    • -f(指定脚本文件)
    • -i(直接修改文件与备份)
    • -E(扩展正则表达式)
  • 常用动作
    • p(print,打印)
    • i(插入内容)与a(追加内容)
    • c、y(替换)
    • d(delete,删除)
    • s(替换)
  • 其他动作
    • l(小写L,打印特殊字符)
    • r(在匹配行后插入指定文件内容)
    • w(将匹配行写入指定文件)
    • 退出、下一行
  • 取反(!)
  • 模式空间与暂存区
  • 其他示例
  • 一些需要注意的点

sed基本结构

sed 选项 [模式1][,模式2] [动作][flag] filename

模式指的是Addresses,有的朋友也会把它直译为地址。

sed的格式非常灵活,导致有时候可读性不好,不信看:

sed '1croot' sed.txt

上面这个命令简单吧,如果对sed不熟悉,晃眼可能还得愣2秒才能反应过来。

所以,我们想要一眼就可能知道sed在干什么,就一定要清楚sed结构。

我们先来看一个简单的例子,说明一下结构。

# -n是选项表示使用静默模式, '2,5p'是动作表示打印2到5行 sed.txt是要处理文件
sed -n '2,5p' sed.txt

上面这个命令也非常简单,但是它几乎包含了sed的全部结构,我们在它的基础上稍微变一下,还能一眼看穿吗?

sed '1~2p' sed.txt
sed  '1,5s/aa/zzzz/g' sed.txt
sed '2s/aa/AA/2' sed.txt
sed '/aa/s/aa/AA/2' sed.txt
sed '/^luck/,+3s/luck/LUCK/g' sed.txt
sed -n '/2024-10-13 06:52:48/,/2024-10-13 06:53:21/w app.log.bak' app.log

我们只要理解结构,就会发现万变不离其中:

Linux sed命令结构

模式部分,我们总结一下:

模式可以包含2部分,表示匹配的区间,模式有下面几种格式:

模式格式示例说明
n,msed ‘3,5p’ sed.txt,表示只打印区间3-5行
nsed ‘5p’ sed.txt,表示只打印第5行,可以看做是sed ‘5,5p’ sed.txt的简写
n,+msed ‘3,+5p’ sed.txt,表示只打印区间3-8行,可以看做是sed ‘3,8(3+5)p’ sed.txt
/xxx/sed ‘/luck/’ sed.txt,表示包含luck的行
/xxx/,/yyy/sed ‘/luck/lovely/’ sed.txt,表示打印区间,从包含luck的行开始,到包含lovely的行结束

模式都是上面的组合,如:

  1. /xxx/,10
  2. /xxx/,+3
  3. 3,/xxx/
  4. /xxx/,/yyyy/
  5. 3,5
  6. 3,+5
  7. 3,$:3到最后一行
  8. /xxx/,~3
  9. 1,~3
  10. 1~3:这个特殊,可以看做初始值1,步长3直到sed行结尾,注意和上2个的区别(文章最后)

选项

选项说明
-nslient静默模式,不输出原来的行,通常与p一起使用
-e多点编辑
-f指定sed命令脚本,-f filename则可以执行filename内的sed动作
-i直接修改读取的文件内容,而不是输出print,危险危险
-E使用扩展表达式
-r和-E等价,表示使用扩展正则表达式

关于扩展正则表达式,可以参考:Linux grep命令详解(多图、多示例)

-n(静默模式)

sed '2,5p' sed.txt
sed -n '2,5p' sed.txt

Linux sed n参数

-e、;(多点编辑,多条命令)

# 打印2到5号,打印每行行号
sed -n -e '2,5p' -e '=' sed.txt# 除了-e还可以使用分号(;),等价于上一个命令
sed -n '2,5p;=' sed.txt# 打印第4行和最后一行
sed -n '4;$p' sed.txt

Linux sed e参数
不知道你有没有发现,-e参数和;指定的命令模式不同,相当于都是独立的指令,如果我们要对同一个模式匹配,做多个动作,怎么办呢?

注意下面2个命令的区别:

# 这相当于是2个指令,按行读取,分别执行2个指令
sed -n '2,5p;=' sed.txt# 这是相当于1个指令,2个动作,对于2到5行这个模式匹配,分别打印和输出行号
sed -n '2,5{p;=}' sed.txt

Linux sed 多动作

-f(指定脚本文件)

sed -n -f sed.action sed.txt

sed.action的内容:

2,5p
=
4,6p

Linux sed f参数

-i(直接修改文件与备份)

sed -i -e '2izzzzzz' -e '$ayyyyyy' sed.txt# -i直接修改文件太危险,可以使用-i.bak修改的同时生成备份文件
# -i后面的作为备份文件的后缀,通常习惯使用.bak
sed -i.bak 's/11/zzzzz/' sed.txt

Linux sed i参数

-E(扩展正则表达式)

sed支持正则表达式,和grep一样,可以使用-E参数来说指定使用扩展正则表达式(不用使用\转义)

在//之间的是正则表达式:/正则表达式/

# 打印以bb开头,aa结尾的行
sed -n -E '/^bb.*aa$/p' sed.txt# 
sed -n '/a.?/p' sed.txt
sed -n -E '/a.?/p' sed.txt

Linux sed E参数
Linux sed E参数

常用动作

动作说明
p、P打印行
s替换指定字符串
a匹配行之后追加行
i匹配行之前插入行
c替换指定行
d删除行

p(print,打印)

# 打印第1个包含bb的行到第一个包含11之间的行(包括匹配行)
sed -n '/bb/,/11/p' sed.txt# 打印第1个以bb开头的行以及接下来的2行
sed -n '/^bb/,+2p' sed.txt# 打印包含luck的行
sed -n '/luck/p' sed.txt#  打印包含OOM 或ERROR的行,忽略大小写
sed -n -E '/OOM|ERROR/Ip' sed.txt# 打印匹配行号
sed -n '/luck/=' sed.txt# 打印最后一行
sed -n '$p' sed.txt
# 打印4行到最后1行
sed -n '4,$p' sed.txt# 打印偶数行,n简单的看就是下1行,所以从第1行开始,打印下1行,就是打印的偶数行
# n本质上的操作是把下一行的数据放入模式空间
sed -n 'n;p' sed.txt
# 打印奇数行
sed -n 'p;n' sed.txt# 表示从第2行开始,每隔2(3-1)行打印
sed -n '2~3p' sed.txt# 打印包含yes的行不区分大小写
sed -n '/[Yy][Ee][Ss]/p' sed.txt# 打印长度大于10的行,可以用来过滤代码行超长的行
sed -E -n '/^.{10}/p' sed.txt# 只打印tcp连接
ss | sed -n '/tcp/p'

Linux sed tcp

i(插入内容)与a(追加内容)

  1. i插入,是在指定行之前insert内容
  2. a追加,是在指定行之后append内容
sed -e '2,3i 插入i' -e '4,5a 追加a' sed.txtsed -e '2,3i 插入i\n插入i2' -e '4,5a 追加a\n追加a2' sed.txt# 格式要求不高,下面这些都可以
sed -e '2,3i插入i' -e '4,5a追加a' sed.txt
sed -e '2i插入i' -e '5a追加a' sed.txt
sed -e '2i 插入i' -e '5a 追加a' sed.txt
sed -e '2i\插入i' -e '5a\追加a' sed.txt
sed -e '2ii插入i' -e '5aa追加a' sed.txtsed -e '2,3i 插入i' -e '$a new year' sed.txt# 在与#开头的行之后的行添加空行
sed '/^#/a\\' sed.txt

Linux sed 插入追加

c、y(替换)

  1. c(change)是用指定内容替换指定行
  2. y是使用指定字符替换对应字符
# 将第2行替换为zzzzzzzzz
sed '2czzzzzzzzz' sed.txt# 将行中的a全部换为z、b全部换为y,/xxx/yyy/其中xxx和yyy一一对应,长度必须相等
sed 'y/ab/zy/' sed.txt

Linux sed 替换行字符

d(delete,删除)

# 删除2到5行
sed '2,5d' sed.txt
# 删除11开头的行以及其后2行的内容
sed '/^11/,+2d' sed.txt# 删除11开头的行到第4行内容
sed '/^11/,4d' sed.txt# 删除空白行
sed '/^$/d' sed.txt

Linux sed 删除

s(替换)

标志位说明
\l把下个字符转换成小写
\L把匹配字母转换成小写,直到\U或\E出现
\u把下个字符转换成大写
\U把匹配字母转换成大写,直到\L或\E出现
\E停止以\L或\U开始的大小写
g表示替换全部
i、I大写i与小写i,表示忽略大小写
&表示引用匹配到的内容
\n表示引用匹配的分组,n为1、2、3…例如\1 \2

注意:\n肯定需要-E参数,没有正则匹配不了分组

sed  's/aa/##/I' sed.txt
sed  's/aa/##/i' sed.txt

Linux sed 替换忽略大小写

# 将文件中每一行的aa替换为zz,g表示替换所有
sed -n 's/aa/zz/g' sed.txt
sed -n 's/a./zz/g' sed.txt
# 使用#作为界定符合和上一个命令等价,也可以使用#、:、|、@等作为界定符
sed -n 's#aa#zz#g' sed.txt
# 这里我们使用:做界定符,因为我要替换的内容本身有/
sed  's:/bin:/sbin:g' /etc/passwd
# 否则,如果使用正斜杠/做界定符,如果替换的内容中本身就有/就要使用\转义(\/)
sed 's/\/bin\/bash/\/bin\/sh/' /etc/passwd
# 换成#就清楚多了,3个#将内容分成2部分,第1部分是要匹配的内容,第2部分是要替换的内容
sed 's#/bin/bash#/bin/sh#' /etc/passwd # 可以使用正则表达式
sed -n -E 's/a.?/zz/g' sed.txt# &引用匹配到的内容
sed -n -E 's/^11/这是匹配到的行:&/g' sed.txt# \1 \2 \3...引用分组(小括号中内容)
# 这里是将匹配到的数字前面加上$
sed -E 's/[^0-9]*([0-9]+)[^0-9]*/$\1 /g' sed.txt# 在所有行前加#
sed 's/^/#/g' sed.txt
# 在所有非#开头的行加#
sed 's/^[^#]/#/g' sed.txt
# 删除所有#开头的行
sed '/^#/d' sed.txt# 将所有字母大写
sed -E 's/(.*)/\U\1/g' sed.txt# 将所有单词首字母大写
sed -E 's/(\b[^\s])/\u\1/g' sed.txt# 给每一行加上双引号
sed 's/.*/"&"/' sed.txt# 为每一行添加上#
sed 's/^/#/' sed.txt# 为包含fuck的行的行尾加上----包含敏感词
sed '/fuck/s/$/----包含敏感词/'# 统计文件单词频次,先用sed按空格拆分为行,排序,统计相同的单词数量
sed 's/ /\n/g' sed.txt | sort | uniq -c

Linux sed模式匹配替换

其他动作

动作说明
=输出行号
w、W将匹配的行写入指定文件
r从文件中读取输入行
l列出非打印字符
q结束或退出sed

l(小写L,打印特殊字符)

这个在处理一些特殊字符的时候非常有用,例如后面我们要说的模式空间测试的时候。

sed -n 'l' sed.txt
sed -n 'l' ascii.txt

Linux sed 打印特殊字符

r(在匹配行后插入指定文件内容)

# 在sed.txt文件中以11开头的行后插入文件sed-r.txt的文件内容,文件必须使用绝对路径
sed '/^11/ r /home/ubuntu/sed-r.txt' sed.txt

Linux sed 插入文件

w(将匹配行写入指定文件)

sed '/^11/ w /home/ubuntu/sed-w.txt' sed.txt

Linux sed 写入文件

退出、下一行

# 打印完第前3行后退出sed
sed '3q' sed.txt# 匹配到luck开头的行,并打印下1行,n是把下1行复制到模式空间
sed '/^luck/{ n; p; }' sed.txt# 匹配到luck开头的行,移动到匹配行的下1行,将这1行的:替换为空格
sed '/^luck/{ n; s/:/ /g; }' sed.txt

Linux sed 下一行

取反(!)

取反有2中操作:

  1. 对模式取反
  2. 对动作取反

  1. 2,5!{p}:表示对模式取反,不打印2-5行
  2. 2,5{!p}:对动作取反,匹配2-5行,但是不打印
  3. 2,5!p:对模式取反,同1,模式匹配的优先级高,先模式后动作,所以模式匹配就把!给消费掉了
seq 11 1 17 | sed -n '2,5!{p}'
seq 11 1 17 | sed -n '2,5{!p;=}'
seq 11 1 17 | sed -n '2,5!p'

Linux sed取反

模式空间与暂存区

sed有一个模式空间,还有一个暂存区(存放临时数据),大致处理流程为:

  1. sed逐行处理,每行内容存在模式空间
  2. 执行print动作打印到屏幕(除非行被删除或者输出被取消)
  3. 清空模式空间,读取下一行到模式空间

理解了上面这些内容,才能理解下面这些命令:

动作说明
h将模式空间内容复制到暂存区
H将模式空间内容追加到暂存区
g将暂存区内容复制到模式空间,原模式空间内容被覆盖
G将暂存区内容追加到模式空间,原模式空间内容被保留
n读取匹配到的行的下1行复制至模式空间,原模式空间内容被覆盖
N读取匹配到的行的下1行追加至模式空间,原模式空间内容被保留
d删除模式空间内容
D删除模式空间开始至\n的内容,对剩余模式空间内容重新执行sed
x交互模式空间与暂存区的内容

便于记忆:

  1. h可以当做holder表示暂存区
  2. g可以当做global表示模式空间
  3. n可以当做next line表示下一行
  4. 小写是覆盖,大写是追加(大内容更多)
# 将所有以11开头的行追加到暂存区,最后追加到最后1行
sed -e '/^11/H' -e '$G' sed.txt

Linux sed 模式空间追加

# 匹配到11的行替换为最近匹配到的bb所在的行
sed -e '/bb/h' -e '/11/x' sed.txt

Linux sed 模式空间交换

我们再来看一个更复杂一点的,反序输出:

# !取反,1!G表示第1行不将暂存追加到模式空间,其他行还是执行
# $!d,表示最后1行不删除模式空间内容,其他行还是执行
seq 4 | sed '1!G;h;$!d'

大概步骤:

步数模式空间暂存区行结束模式空间
111-(模式空间内容被删除,没有内容输出)
22-1(将上1步暂存区的1,追加到模式空间)2-1(将前面模式空间的内容拷贝到暂存区)-
33-2-1(将上1步暂存区的2-1,追加到模式空间)3-2-1-
44-3-2-14-3-2-14-3-2-1(最后1行的时候模式空间内容不删除,执行print)

更多示例:

# 删除包含@Test的下一行
sed '/@Test/{n,d}' sed.txt# 把偶数行合并到前一行
sed '{N;s/\n/ /}' sed.txt# 删除多余空行
sed -i.bak '/^$/{N;/\n$/D}' sed.txt

Linux sed删除多余空行

其他示例

查看我们已经有grep了,sed主要用来预处理文件,所以通常是find的最佳搭档。

对find不熟悉的朋友,可以参考:Linux find命令详解与实际使用

find . -name  "*.config" -mmin -60 | xargs sed -i 's/127\.0\.0\.1/localhost/g' find . -name  "*.log" -mmin -60 -exec sed -E '/ierror|oom/I w /home/unbuntu/log.log' {} \;# 删除空行
sed  '/^$/d' sed.txt
# 删除空行及空白行
sed -E '/^$\s*/d' sed.txt
# 把以#开头、空行、空格的行过虑掉
sed '/^#/d; /^$/d ;/^ /d' sed.txt# 删除包含fuck的行
sed  '/fuck/d' sed.txt# 打印所有以#开头的数据
sed -n '/^#/p' sed.txt
# 查看nginx代理
sed -n '/proxy_pass/p' nginx.conf
# 查看nginx配置的域名
sed -n '/server_name/p' nginx.conf# 将第一行替换成:#!/bin/bash,例如想将sh换成bash
find . -name  "*.sh" | sed -i '1c#!/bin/bash'# 在文件第1放插入:#!/bin/bash
find . -name  "*.sh" | sed -i '1i#!/bin/bash'# 将所有以fuck开头的内容向后删掉
sed -E 's/fuck.*//'  sed.txt# 在包含aa行的下方插入一行
sed '/aa/a\\' sed.txt
# 在包含@Test行的上方插入一行
sed '/@Test/i\\' FindTest.java# 将指定词组删除
sed -n 's/[fuck,草,屏蔽词]//g' sed.txt

一些需要注意的点

sed命令的$表示最后1行的时候,不是只文件的最后一行,而是指命令处理的最后1行。

这一点和awk的NR变量一样,对awk感兴趣的朋友可以看一下:Linux awk命令详解-参数-选项-内置变量-内置函数-脚本(多图、多示例)

当然,这通常是在多文件的时候才会有区别

sed -n '$p' sed.txt
sed -n '$p' sed.txt num.txt
sed -n -s '$p' sed.txt num.txt

Linux sed多文件

在p动作的时候也可以指定忽略大小写,但是必须用大写i

# 忽略大小写,打印包含aa|AA|Aa|aA的行
sed -n '/aa/Ip' sed.txt
# 小写的i不行
sed -n '/aa/ip' sed.txt

Linux sed忽略大小写

sed -n '/zz/,~2{=;p}' sed.txt

Linux sed 模式

sed -n '1~2{=;p}' sed.txt
sed -n '1,~2{=;p}' sed.txt

Linux sed 模式

最后,命令细节非常多,如有有疑问,最好的方式:man sed

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

开箱即用!265种windows渗透工具合集--灵兔宝盒

【渗透工具箱】灵兔宝盒-Rabbit_Treasure_Box_V1.0.1 介绍 Rabbit_Treasure_Box_V1.0.1是一款Windows渗透工具箱,集成Dawn Launcher管理,便捷备份更新。内含脚本工具及在线安全工具,覆盖信息收集、漏洞利用、逆向破解、蓝队防御等多领域&am…

对标 Windows Copilot 的 UOS AI,升级后更能打了

进入 2024 年,AI 应用迎来大爆发,不仅各类应用纷纷宣称“AI 赋能”,操作系统也不例外。前有 Windows Copilot,后有 Apple Intelligent,手机行业更是积极,各种 AI 手机纷纷发布。国产信创系统自然也不甘落后…

【LeetCode】每日一题 2024_11_2 使两个整数相等的位更改次数(位运算/模拟)

前言 每天和你一起刷 LeetCode 每日一题~ LeetCode 启动! 题目:使两个整数相等的位更改次数 代码与解题思路 先读题: 题目要我们把 n 这个数字转换成 k 这个数字,但是只能是二进制位 1 转换成 0 纯模拟的解法: f…

2024 开源社年度评选

开源社(英文名称为“KAIYUANSHE”)成立于2014年,是由志愿贡献于开源事业的个人志愿者,依 “贡献、共识、共治” 原则所组成的开源社区。开源社始终维持 “厂商中立、公益、非营利” 的理念,以 “立足中国、贡献全球&am…

【MATLAB源码-第204期】基于matlab的语音降噪算法对比仿真,谱减法、维纳滤波法、自适应滤波法;参数可调。

操作环境: MATLAB 2022a 1、算法描述 语音降噪技术的目的是改善语音信号的质量,通过减少或消除背景噪声,使得语音更清晰,便于听者理解或进一步的语音处理任务,如语音识别和语音通讯。在许多实际应用中,如…

C语言 | Leetcode C语言题解之第542题01矩阵

题目: 题解: /*** Return an array of arrays of size *returnSize.* The sizes of the arrays are returned as *returnColumnSizes array.* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().*/ type…

[SWPUCTF 2022 新生赛]Power! 反序列化详细题解

知识点: PHP反序列化(执行顺序) 构造POP链 代码审计 题目主页: 输入框可以输入内容,习惯性先查看一下页面的源代码,收集信息 发现源码中有提示参数source 先不急,再看一下其他信息 是apache服务器,php版本为7.4.30 url传参 ?sourceindex.php 回显了index.php的源码 …

docker下迁移elasticsearch的问题与解决方案

欢迎来到我的博客,代码的世界里,每一行都是一个故事 🎏:你只管努力,剩下的交给时间 🏠 :小破站 docker下迁移elasticsearch的问题与解决方案 数据挂载报错解决权限问题节点故障 直接上图&#x…

Spark 的介绍与搭建:从理论到实践

目录 一、分布式的思想 (一)存储 (二)计算 二、Spark 简介 (一)发展历程 (二)Spark 能做什么? (三)spark 的组成部分 (四&…

Python GUI 编程:tkinter 初学者入门指南——微调框

在本教程中,将介绍如何创建 Tkinter Spinbox 微调框小部件。 Python 中 Tkinter 中的 Spinbox 小部件用于从指定的给定值范围内选择一个值。 此外,可以直接在 Spinbox 小组件中输入值,就像使用单行文本框小组件一样。 要创建 Spinbox 小部件…

人保财险(外包)面试分享

前言: 这是本月面的第三家公司,太难了兄弟们,外包都不好找了,临近年底,金九银十已经错过了,金三银四虽然存在,但按照这几年的行情,金九银十和金三银四其实已经是不复存在了&#xf…

Redis - 数据库管理

Redis 提供了⼏个⾯向Redis数据库的操作,分别是dbsize、select、flushdb、flushall命令, 本机将通过具体的使⽤常⻅介绍这些命令。 一、切换数据库 select dbIndex 许多关系型数据库,例如MySQL⽀持在⼀个实例下有多个数据库存在的&#…

大数据挖掘有哪些技术要点?

大数据挖掘的主要方法和技术有:分类、聚类、关联规则、回归分析、时间序列分析、文本挖掘、社交网络分析、可视化技术等。通过大数据挖掘,企业和研究机构能够从海量数据中提取有价值的信息和知识,促进决策优化和业务创新。 一、分类 分类是大…

Python小游戏23——捕鱼达人

首先,你需要安装Pygame库。如果你还没有安装,可以使用以下命令进行安装: 【bash】 pip install pygame 运行效果展示 接下来是示例代码: 【python】 import pygame import random # 初始化Pygame pygame.init() # 屏幕尺寸 SCREEN…

项目模块十七:HttpServer模块

一、项目模块设计思路 目的:实现HTTP服务器搭建 思想:设计请求路由表,记录请求方法与对应业务的处理函数映射关系。用户实现请求方法和处理函数添加到路由表,服务器只接受请求并调用用户的处理函数即可。 处理流程: …

GS-SLAM论文阅读--High-Fidelity SLAM Using Gaussian Splatting

前言 这篇文章是几个月之前的IROS2024了,之前忘记看了,但是最近看到,觉得有一些值得参考的部分,接下来仔细阅读一下。 文章目录 前言1.背景介绍2.关键内容2.1 建图2.2 跟踪2.3总体流程 3.文章贡献 1.背景介绍 3DGS的连续建图存在…

App渠道来源追踪方案全面分析(iOS/Android/鸿蒙)

一、App 渠道来源追踪概述 渠道来源统计/追踪,其原理都可以称之为归因,归因是用于判断用户在什么原因、什么时间、什么场景下载了 App,以及打通他们在激活 App 后进行的一系列操作(比如注册、付费、加购等)。 渠道来…

group_concat配置影响程序出bug

在 ThinkPHP 5 中,想要临时修改 MySQL 数据库的 group_concat_max_len 参数,可以使用 原生 SQL 执行 来修改该值。你可以通过 Db 类来执行 SQL 语句,从而修改会话(Session)级别的变量。 步骤 设置 group_concat_max_l…

物联网赋能的人工智能图像检测系统

一、引言 在数字化时代,物联网(IoT)技术已经成为我们生活中不可或缺的一部分,极大地优化了我们的交通出行和医疗服务。物联网的核心优势在于其卓越的连接能力,它能够构建和连接庞大的资源数据库,为智能化图…

【python笔记】os库中ctime、mtime和atime的区别

ctime Creation Time文件或目录的创建时间 返回秒级时间戳 os.path.getctime(file_path) os.stat(file_path).st_ctime 返回纳秒级时间戳 os.stat(file_path).st_ctime_ns mtime Modification Time文件或目录的最后修改时间 返回秒级时间戳 os.path.getmtime(file_path) os.sta…