在文本处理的世界里,SED流编辑器宛如一把瑞士军刀,功能强大且实用。无论是处理海量数据文件,还是批量修改配置文件,SED都能展现出其独特的魅力。今天,就让我们一同深入探索SED的奇妙世界,掌握其基础知识和实用技巧,让文本处理变得轻松自如。

一、SED:文本处理的神器

(一)SED是什么

SED是一款流编辑工具,专门用于对文本进行过滤与替换工作。它能够以一种高效且灵活的方式处理文本,尤其适用于大规模文本文件的操作。例如,当你面对几十个配置文件需要进行统一修改时,SED就能发挥巨大作用,让你在短时间内完成任务。

(二)SED的工作流程

  1. 读取文件:SED通过文件或管道读取文件内容,每次仅读取一行,这使得它在处理大数据文件时不会占用过多内存,保证了处理效率。
  2. 模式空间操作:读取的内容会被复制到缓冲区,也就是模式空间(pattern space)。在这里,SED根据指令对内容进行处理。
  3. 输出结果:处理后的结果默认输出至标准输出,即屏幕上。如果需要,也可以将结果保存到文件中。

以下是SED工作流程的示意图:

输入
------------------------------------------------
|
|
v
读取一行内容,并复制到模式空间 <------------ sed指令
|
|
v
------------------------------------------------
输出经过处理后的内容

二、SED基本语法:开启文本处理之旅

(一)基本语法格式

sed Options... [script] [inputfile...]

其中,Options是SED程序本身的选项,用于控制SED的行为;script是脚本指令,用于指定对文件内容的操作;inputfile是输入文件,如果没有指定,则SED默认对标准输入进行处理(如键盘输入)。

(二)常用选项解析

  1. 显示版本和帮助

    • --version:显示SED版本。
    • --help:显示帮助文档。
  2. 控制输出
    • -n,--quiet,--silent:静默输出,屏蔽SED程序自动打印模式空间内容的功能。
  3. 执行脚本指令
    • -e script:允许多个脚本指令被执行。
    • -f script-file, --file=script-file:从文件中读取脚本指令,方便编写自动脚本程序。
  4. 修改源文件(谨慎使用)
    • -i,--in-place:直接修改源文件,处理后的内容将覆盖源文件内容。
  5. 其他选项
    • -l N, --line-length=N:指定l指令输出的行长度,l指令用于输出非打印字符。
    • --posix:禁用GNU SED扩展功能。
    • -r, --regexp-extended:在脚本指令中使用扩展正则表达式。
    • -s, --separate:控制SED对多个文件名的处理方式。
    • -u, --unbuffered:最低限度缓存输入与输出。

(三)简单案例演示

  1. 追加与插入

    假设我们有一个名为test.txt的文件,内容如下:
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.0.1
NETMASK=255.255.255.0
GATEWAY=192.168.0.254
  • 在第二行后添加TYPE=Ethernet
sed '2a TYPE=Ethernet' test.txt
  • 在第三行前添加TYPE=Ethernet
sed '3i TYPE=Ethernet' test.txt
  1. 替换

    将文件中所有的yes替换为no
sed's/yes/no/g' test.txt
  1. 删除

    删除第3至4行的内容:
sed '3,4d' test.txt
  1. 使用正则表达式定位操作行
  • 匹配到包含ONBOOT的行,并在其后添加TYPE=Ethernet
sed '/ONBOOT/a TYPE=Ethernet' test.txt
  • 匹配以GATEWAY开始的行,并删除该行:
sed '/^GATEWAY/d' test.txt
  1. 从脚本文件中读取指令

    创建一个名为sed.sh的脚本文件,内容如下:
/^$/d

这条指令的作用是删除空白行。然后执行:

sed -f sed.sh test.txt
  1. 执行多个指令的方法
  • 使用分号隔开指令:
sed's/yes/no/;s/static/dhcp/' test.txt
  • 使用-e选项:
sed -e's/yes/no/' -e's/static/dhcp/' test.txt
  • 利用分行指令:
sed '
s/yes/no/
s/static/dhcp/' test.txt

三、正则表达式:精准定位文本

(一)确定操作地址

  1. 行号指定

    • number:指定输入文件的唯一行号,如2d表示删除第二行。
    • first~step:以first开始,操作步长为step,如1~2表示打印文件的奇数行。
    • $:匹配文件的最后一行。
  2. 正则表达式匹配
    • /regexp/:通过正则表达式匹配操作地址,例如/ONBOOT/匹配包含ONBOOT的行。
    • \cregexpc:匹配扩展正则表达式,c字符可以使用任意字符替代。
  3. 范围指定
    • addr1,addr2:匹配从操作地址1到操作地址2的所有行,如2,8d删除2至8中间的所有行。
    • addr1,+N:匹配地址1以及后面的N行内容。

(二)正则表达式概述

  1. 字符匹配

    • char:字符本身匹配字符本身,如/abc/定位包含abc的行。
  2. 数量限定符
    • *:匹配前面表达式出现了0或若干次,如/a*/可以找到aaaaaa等。
    • \+(扩展正则表达式):匹配前面表达式的1次或多次。
    • \?(扩展正则表达式):匹配前面表达式的0次或1次。
    • \{i\}:匹配前面表达式的i次(i为整数),如a\{3\}找到aaa
    • \{i,j\}:匹配前面表达式的ij次,如a\{1,2\}找到aaaaaa
    • \{i,\}:匹配前面表达式至少i次。
  3. 分组与引用
    • ():将内的模式存储在保留空间,最多可存储9个独立子模式,可通过转义\1\9重复保留空间的内容。
  4. 其他元字符
    • .(点):匹配任意字符。
    • ^:匹配行的开始,如^test匹配所有以test开始的行。
    • $:匹配行的结尾,如test$匹配所有以test结尾的行。
    • []:匹配括号中的任意单个字符,如a[nt]匹配anat
    • [^]:匹配不包含在[]中的字符,如[^a-z]匹配除a-z以外的字符。
    • \n:匹配换行符。
    • \char:转义特殊字符,如\*匹配字面意义上的星号。

四、SED脚本指令:实现多样化操作

(一)注释(#)

注释行以#开始,如果#后面的字符为n,则屏蔽SED程序的自动输出功能,等同于命令选项-n

(二)替换(s)

  1. 基本格式

    [address]s/pattern/replacement/flags

    其中,address为操作地址,s为替换指令,/pattern/匹配要替换的内容,/replacement/为替换的内容,flags可以是:

    • n(1至512之间的数字):表示对模式空间中指定模式的第n次出现进行替换。
    • g:对模式空间的匹配进行全局更改,没有g则仅第一次匹配被替换。
    • p:打印模式空间的内容。
    • w file:将模式空间的内容写到文件file中。
  2. 示例

    假设有一个名为test.txt的文件,内容如下:
<html>
<title>First Web</title>
<body>Hello the World! <body>
</html>

将样本文件中的第二个<body>替换为</body>

编写sed.sh脚本如下:

/body/{
s//\/body/2
}

执行sed程序:

sed -f sed.sh test.txt

结果为:

<html>
<title>First Web</title>
<body>Hello the World!</body>
</html>

(三)删除(d)

删除指令删除匹配的行,且会改变SED脚本中命令的执行顺序。因为匹配的行被删除后,模式空间变为“空”,SED脚本后续命令不再执行,而是读取新的输入行,从头开始执行命令。

(四)追加(a)

在匹配行后追加内容。例如,对于文件test.txt

DEVICE=eth0
ONBOOT=yes
BOOTPROTO=static
NETMASK=255.255.255.0
GATEWAY=192.168.0.254

执行sed '/static/a IPADDR=192.168.0.1' test.txt,会在包含static的行后添加一行IPADDR=192.168.0.1

(五)插入(i)

在匹配行前插入内容。如sed '/NETMASK/i IPADDR=192.168.0.1' test.txt,会在包含NETMASK的行前添加一行IPADDR=192.168.0.1

(六)更改(c)

更改匹配行的内容。例如,sed '/ONBOOT/c ONBOOT=yes' test.txt会将包含ONBOOT的行(整行)替换为ONBOOT=yes

(七)列印(l)

显示模式空间中的内容,显示非打印字符,一般与-n一起使用,否则会输出两次。例如,sed -n '1,2l' test.txt会显示文件的第一、二行内容及换行符(以$表示)。

(八)转换(y)

按字符进行转换。例如,对于文件test.txt

DEVICE=eth0
ONBOOT=yes
BOOTPROTO=static
netmask=255.255.255.0
GATEWAY=192.168.0.254

编写sed.sh脚本:

/.*/{
/netmask/y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
}

执行sed -f sed.sh test.txt,会将netmask中的小写字母转换为大写字母。

(九)打印(p)

作用类似于l,但不显示非显示字符,一般与-n配合使用。如sed -n '1,2p' test.txt仅显示第一、二行内容。

(十)读写文件(r,w)

  1. 读取文件(r)

    [line-address]r file,例如,有name.txtmail.txt两个文件:

    name.txt内容:
Jacob
Tom
Jerry

mail.txt内容:

jacob@gmail.com
tom@gmail.com
jerry@gmail.com

编写sed.sh脚本:

/.*/{
$r mail.txt
}

执行sed -f sed.sh name.txt,会在name.txt文件末尾添加mail.txt的内容。

2. 写入文件(w)

[address]w file,可以将指定行的内容写入到文件中。

(十一)退出(q)

匹配地址后退出SED脚本。例如,sed '10q' test.txt会打印文件前10行内容后退出。

(十二)下一步(n)

[address]n,输出模式空间中的内容,然后读取输入的下一行。例如,对于文件name.txt

Jacob
Tom
Jerry

编写sed.sh脚本:

/.*/{
n
/.*/d
}

执行sed -f sed.sh name.txt,会删除偶数行,结果为:

Jacob
Jerry

(十三)Next(N)

多行Next(N)命令通过读取新的输入行,并将它添加到模式空间的现有内容之后,来创建多行模式空间。模式空间的最初内容与新的输入行之间用换行符分隔。例如,对于文件test.txt

111
222
222
333

编写sed.sh脚本:

#n
/222/{
N
l
}

执行sed -f sed.sh test.txt,结果如下:

222\n222

(十四)Print(P)

多行打印(P)与打印(p)稍有不同,该命令仅输出多行模式空间中的第一部分,直到第一个插入的\n换行符为止。例如,对于文件test.txt

111
222
333
444
555
666

编写不同的sed.sh脚本并执行,结果如下:

  • 脚本1:
/.*/{
N
}

结果:

111
222
333
444
555
666
  • 脚本2:
/.*/{
N
l
}

结果:

111\n222$
111
222\n333$
222
333\n444$
333
444\n555$
444
555\n666$
555
666
  • 脚本3:
/.*/{
N
P
}

结果:

111
111
222
222
333
333
444
444
555
555
666
666
  • 脚本4:
/.*/{
N
p
}

结果:

111
222
111
222
333
444
333
444
555
666
555
666

(十五)Delete(D)

删除命令(D)删除模式空间中直到第一个插入的换行符(\n)前的这部分内容,它不会读入新的输入行,并返回SED脚本的顶端,使得剩余指令继续应用于模式空间中剩余的内容。

(十六)Hold(h,H),Get(g,G)

模式空间用于存放当前输入行,还有一个保持空间(hold space)。可以使用以下命令在两者之间移动数据:

  1. Hold(h|H):将模式空间的内容复制或追加到保持空间。
  2. Get(g|G):将保持空间的内容复制或追加到模式空间。
  3. Exchange(x):交换保持空间与模式空间的内容。

例如,对于文件test.txt

1
2
11
22
111
222

编写sed.sh脚本:

/1/{
h
d
}
/2/{
G
}

执行sed -f sed.sh test.txt,结果为:

2
1
22
11
222
111

(十七)branch,test

分支(b)和测试(t)命令用于控制SED脚本的执行流程。分支命令是无条件转移,测试命令用于有条件转移,测试只有当替换命令改变当前行成功时才会执行。标签是任意不多于7个字符的序列,以冒号开始,如:mylable。在分支或测试命令

作者:代老师的编程课

出处:https://zthinker.com/

如果你喜欢本文,请长按二维码,关注 Java码界探秘

.

超详细!SED流编辑器从入门到精通的更多相关文章

  1. Linux三剑客之sed流编辑器

    一.功能说明 Sed是Stream Editor(流编辑器)缩写,是操作.过滤和转换文本内容的强大工具.常用功能有增删改查,过滤,取行. 二.语法格式 Usage: sed [options] [se ...

  2. 【Shell案例】【!~//、grep反向查找、sed流编辑器】13、去掉所有包含this的句子

    描述写一个 bash脚本以实现一个需求,去掉输入中含有this的语句,把不含this的语句输出示例:假设输入如下:that is your bagis this your bag?to the deg ...

  3. Linux下的sed流编辑器命令详解

    sed是stream editor的简称,也就是流编辑器.它一次处理一行内容,处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内 ...

  4. Linux sed 流编辑器

    sed是stream editor的简称,也就是流编辑器.盗用一张图片解释原理 命令格式: SYNPPSIS: sed [OPTION]… {script-only-if-no-other-scrip ...

  5. sed流编辑器

    一.前言 (一).sed 工作流程 sed 是一种在线的.非交互式的流编辑器,它一次处理一行内容.处理时,把当做前处理的行存储在临时缓存区中,成为“模式空间”(pattern space),接着用se ...

  6. Shell:sed流编辑器

    转载:http://blog.sina.com.cn/s/blog_ac9fdc0b0101lvdv.html sed和awk是永远地痛,学了又忘,主要是木有横向对比过,所以总把握不到精髓.它可以完美 ...

  7. Python入门教程 超详细1小时学会Python

    Python入门教程 超详细1小时学会Python 作者: 字体:[增加 减小] 类型:转载 时间:2006-09-08我要评论 本文适合有经验的程序员尽快进入Python世界.特别地,如果你掌握Ja ...

  8. Python入门教程 超详细1小时学会Python

    Python入门教程 超详细1小时学会Python 本文适合有经验的程序员尽快进入Python世界.特别地,如果你掌握Java和Javascript,不用1小时你就可以用Python快速流畅地写有用的 ...

  9. Shell 基础 -- 流编辑器 sed 详解

    一.流编辑器 sed 与命令 sed Linux 中,常使用流编辑器 sed 进行文本替换工作.与常使用的交互式编辑器(如vim)不同,sed 编辑器以批处理的方式来编辑文件,这比交互式编辑器快得多, ...

  10. 流编辑器sed知识点总结

    sed(流文本编辑器)     每次读取一行到模式空间中,     修改的sed模式空间中的内容,并不会修改源文件,     继而输出模式空间的内容,     最后删除模式空间中的内容. sed [O ...

随机推荐

  1. Figma 学习笔记 – Team Library Style and Component

    Design System 我们做设计通常会 Follow 一个 Design System, 比如 Material Guide. 里头会定义 Font, Color, Effect (Elevat ...

  2. sicp每日一题[2.13-2.16]

    Exercise 2.13 Show that under the assumption of small percentage tolerances there is a simple formul ...

  3. Spring —— 依赖自动装配

    依赖自动装配   IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配 自动装配方式 按类型(常用) 按名称 按构造方法 不启用自动装配    注意: 自动装配用于引 ...

  4. 暑假集训CSP提高模拟18

    \[暑假集训CSP提高模拟 \ 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1 \] Very good problem, this make my news rotate. ...

  5. 《Vue.js 设计与实现》读书笔记 - 第6章、原始值的响应式方案 & 响应式总结

    第6章.原始值的响应式方案 6.1 引入 ref 的概念 既然原始值无法使用 Proxy 我们就只能把原始值包裹起来. function ref(val) { const wrapper = { va ...

  6. token有⼀定的失效性,过期了该怎么做?

    token 失效分为主动失效和被动失效 主动失效 就是自己设置函数检查token是否失效了, 主要步骤 :1 1.在登录的时候记录存储token的时间, 2. 在request文件,设置一个函数,用来 ...

  7. Vue中mixins(混入)的介绍和使用

    为什么引进 mixins 随着项目的开发,组件越来越多 ,这就导致了在各个组件中需要编写功能相同的代码段,重复地定义这些相同的属性和方法,导致代码地冗余,还不利于后期代码的维护 混入mixins 的创 ...

  8. Android复习(四)权限—>概览

    权限概述 许可 的目的是保护Android用户的隐私.Android应用必须获得访问敏感用户数据(例如联系人和SMS)以及某些系统功能(例如相机和互联网)的权限.根据功能的不同,系统可能会自动授予权限 ...

  9. 《刚刚问世》系列初窥篇-Java+Playwright自动化测试-2-环境准备与搭建-基于Maven(详细教程)

    1.简介 上一篇宏哥已经讲解和分享了如何通过引入jar包来搭建Java+Playwright自动化测试环境,这一种是比较老的方法,说白了就是过时的老古董,但是我们必须了解和知道,其实maven搭建无非 ...

  10. Nuxt.js 应用中的 build:done 事件钩子详解

    title: Nuxt.js 应用中的 build:done 事件钩子详解 date: 2024/10/21 updated: 2024/10/21 author: cmdragon excerpt: ...