sed 是面向行处理的,但是有时可能希望针对多行作为一个单位进行处理,在 sed 中这也是可行的,本文将介绍如何使用 sed 来同时处理多行文本

理论基础

模式空间(Pattern Space):是一块活跃的缓冲区,sed 命令处理行时都

会将文本行读入到该空间执行相关的脚本,默认情况下每次只会从输入中读取一行输入文本到该空间中进行处理。

保持空间(Hold Space):该空间的作用是临时保存 “模式空间” 中处理的文本行

由于 sed 一般是直接在 “模式空间” 中对文本数据进行处理的,因此如果能够改变 “模式空间” 读取文本数据的行为,即可实现将“多行文本数据作为一个处理单位进行处理” 的功能。而要改变 “模式空间” 的默认行为,可以通过 DGHNP等命令进行处理

多行文本处理

读取行

如果只是希望读取下一行,那么普通的 n 命令就可以做到,例如,如果希望将所有出现 “the” 的的行的下一行进行删除,可以执行如下的命令:

# n 命令读取下一行,d 命令进行删除
sed '/the/{n ; d}' data.txt

这里的 n 命令只会读取单行数据文本,然后进行对应的脚本进行处理,本质上在 “模式空间” 中还是只针对单行。如果要合并出现 ‘,’ 的两行,可以使用 N 命令来将读取到的文本行加入到 “模式空间” 中,如下所示:

# 注意将 \n 替换成空格,否则可能无法看到合并的结果
sed '/,/{N; s/\n/ /}' data.txt

注意: 由于 N 命令是获取下一行,因此如果处理的是最后一行的话,由于最后一行没有数据了,因此在读取到最后一行时,会停止 sed,使得最后一行的替换操作无法进行。

删除行

d 命令会删除匹配的行,当和 N 命令一起使用时可能不会达到你想要的结果,因此应该避免在使用 N 命令的同时使用 d 命令,为此可以考虑采用 D 命令来代替 d 命令进行删除

D 命令和 d 命令最大的不同在于 D 命令只会删除 “模式空间” 中的第一行,而不是将整个 “模式空间” 的所有文本行作为一个单元进行处理

D 命令的独特之处在于强制 sed 回到脚本的执行处,对同一 “模式空间” 中的内容重新执行这些脚本内容,

多行打印

当多行匹配时,通过 p 命令可以打印出当前匹配模式中存在的所有文本行,有时可能并不希望发生这样的行为,为此,可以通过 P 命令,该打印命令只会打印 “模式空间” 中的第一行文本内容

取反命令

可以通过在命令选项前加上 ! 来使得原有的命令无法生效,例如,前文提到,N 命令在处理最后一行时会关闭 sed,使得最后一行的内容无法被正确处理,为此,可以通过加入 ! 命令来禁用最后一行的行为,如下所示:

sed '$!N; s/the/a/' data.txt

现在,sed 就能够按照预期地将所有的文本行进行相关的处理

保持空间的相关操作

”保持空间“ 有以下五种选项进行对应的操作,如下表所示:

命令 描述
h 将模式空间中的内容复制到保持空间
H 将模式空间中的内容附加到保持空间
g 将保持空间中的内容复制到模式空间
G 将保持空间中的内容附加到模式空间
x 交换模式空间和保持空间的内容

例如,如果想要反向输出输入流中的文本内容,结合上文的取反命令,可以执行如下的脚本:

sed -n '1!G; h; $p' data.txt

解释:G 命令本身会将保持空间的内容附加到模式空间中,1G 的命令就是将保持空间的内容附加到模式空间的第一行,然而,加上 ! 排除命令之后,使得 1G 的行为变成反向附加到模式空间中;通过 h 命令将模式空间中的内容复制到保持空间;$p 表示每次当到达数据流的末尾时,打印模式空间中的内容

改变流

sed 通过顺序处理输入流来对每一行的数据执行对应的脚本,直到数据流结束(D 命令除外),sed 编辑器提供了一个方法来改变脚本的执行流程。

分支

分支的主要目的是排除某些文本行,使得它们不会执行对应的脚本,具体的使用格式如系所示:

[address]b [label]

例如,如果不希望 data.txt 中的 \([2,3]\) 的文本行不会执行替换脚本,可以执行类似如下的命令:

sed '2,3b; s/the/a/' data.txt

[label] 是类似 goto 语句的结构,如果希望当匹配到 first 文本时,跳转到执行不同的脚本,可以执行类似下面的命令:

sed '{/first/b jump1; s/This/No Jump/
:jump1
s/This/Jump Here/
}' data.txt

当匹配到 “first” 时,则会将执行将 ”This“ 替换为 ”Jump Here“ 的脚本,而不是替换成为 ”No Jump“

注意: 标签名的最大长度为 \(7\) 个字符

测试

和分支命令类似,测试命令 t(test)也可以用来改变 sed 编辑器脚本的执行流程,该命令和 if 语句类似。

使用格式如下:

[address]t [label]

例如,如下的脚本:

sed '{
s/first/matched/
t
s/This/No Matched/
}' data.txt

当处理的文本包含 ”first“ 时,会将 ”first“ 替换为 ”matched“,否则将该文本中的 ”This“ 替换为 ”No Matched“

测试命令 t 同样可以使用和分支类似的标签语义

模式替代

替换命令 s 已经十分了解,试想一下这样一种情况:希望为某个单词加上引号,似乎一般的 s 命令不能完美解决这个问题(无法知道匹配到的实际单词),为了解决这个问题,在传统的 Unix 中提供了 ‘&’ 符号用于表示匹配到的字符串,因此,如果希望给 ”the“ 加上引号,可以执行如下的脚本:

sed 's/th./"&"/' data.txt

有时可能希望替换掉一个字符串中的单词,那么可以考虑使用括号来进行单独的替换,括号表示一个子模式,如下所示:

# \1 表示匹配到的子模式
echo "This is System Administrator manual" | sed 's/\(System\).Administrator/\1 User/'

注意:子模式的括号需要使用 \ 进行转义,否则会被视为一般的字符

”\1“ 表示第一个括号的子模式,”\2“ 表示第二个括号的子模式…………

结合正则表达式可能使用得更加得心应手

参考:

[1] 《Linux 命令行与 Shell 脚本编程大全》

[2] https://www.gnu.org/software/sed/manual/sed.html

sed 命令进阶的更多相关文章

  1. sed命令总结-Linux

    sed命令总结-Linux linuxsed 2018年02月08日 19时27分57秒 命令语法经常忘记,每次总是看笔记不切实际,记不起来的要多查manual,本次总结按照manual总结,希望下次 ...

  2. sed命令总结

    目录 1.概述 2.查 1.打印整行(一或多) 2.正则打印包含关键字的行 2.增 3.删 4.改 5.后向引用 6.结合 7.练习 我叫张贺,贪财好色.一名合格的LINUX运维工程师,专注于LINU ...

  3. 文本处理三剑客之sed命令

    第十八章.文本处理三剑客之sed命令 目录 sed介绍 sed命令常用选项 sed常用编辑命令 sed使用示例 sed高级语法 18.1.sed简介 sed全名stream editor,流编辑器,s ...

  4. linux shell 用sed命令在文本的行尾或行首添加字符

    转自 http://www.cnblogs.com/aaronwxb/archive/2011/08/19/2145364.html 昨天写一个脚本花了一天的2/3的时间,而且大部分时间都耗在了sed ...

  5. linux sed命令详解

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

  6. sed命令详解

    搜索 纠正错误  添加实例 sed 功能强大的流式文本编辑器 补充说明 sed 是一种流编辑器,它是文本处理中非常中的工具,能够完美的配合正则表达式使用,功能不同凡响.处理时,把当前处理的行存储在临时 ...

  7. Linux安全基础:sed命令的使用

    sed 是一个很好的文件处理工具,本身是一个管道命令,主要是以行为单位进行处理,可以将数据行进行替换.删除.新增.选取等特定工作. Sed本质上是一个编辑器,但是它是非交互式的,这点与VIM不同:同时 ...

  8. [转]sed命令详解

    转载:http://blog.chinaunix.net/u/22677/showart_1076318.html   1.简介 sed是非交互式的编辑器.它不会修改文件,除非使用shell重定向来保 ...

  9. sed命令

    sed是一个很好的文件处理工具,本身是一个管道命令,主要是以行为单位进行处理,可以将数据行进行替换.删除.新增.选取等特定工作,下面先了解一下sed的用法sed命令行格式为:         sed ...

  10. sed 命令使用

    ios 的sed 命令 跟linux  sed 命令有区别 # 所有的a 替换成b sed -i "" 's/a/b/g' #删除掉所有包含a的行 sed -i "/a/ ...

随机推荐

  1. POI 操作sheet.shiftRows注意点

    sheet.shiftRows后使用getRow/getCell会导致NullPointException 正确使用应该是CreateRow CreateCell

  2. HTTPS相比HTTP为什么安全

    HTTPS(超文本传输协议[安全]) 1.HTTPS为什么叫安全的超文本传输协议 在HTTPS中,S是Security的意思,是安全的意思,而HTTP是超文本传输协议,这就不得不谈起HTTP在安全方面 ...

  3. linux常用命令(六)

    用于查找系统文件的相关命令 grep find locate grep:查找文件中符号条件的字符串(关键词) 命令语法:grep [选项] 查找模式 [文件名] 选项 选项含义 -E 模式是一个可扩展 ...

  4. linux常见命令(四)

    用于查看日期和时间的相关命令 cal date hwclock cal:显示日历信息 命令语音:cal [选项] [[[日]月]年] 选项 选项含义 -j 显示出给定月中的每一天是一年总的第几天(从1 ...

  5. Thinking in Java 4th Edition Source Code

    Thinking in Java 4th Edition Source Code Instructions for downloading, installing and testing the so ...

  6. HCTF 2023 wp

    HCTF 2023 wp 一.Misc 1.玩原神玩的 分析:附件为一张图片 观察最后一行,明显有flag的格式 搜索得知是 对照得flag为:hctf{yuanlainiyewanyuanshenh ...

  7. 从一次Kafka宕机说起(JVM hang)

    一.背景 时间大概是在夏天7月份,突然收到小伙伴的情报,我们线上的一个kafka实例的某个broker突然不提供服务了,也没看到什么异常日志,反正就是生产.消费都停了.因为是线上服务,而且进程还在,就 ...

  8. C++中const和constexpr的多文件链接问题

    C++语言支持分离编译,在多文件编程中:变量或函数可以被声明多次,但却只能被定义一次.如果要在多个文件中使用同一个变量,变量的定义能且只能出现在一个文件中,在其他使用该变量的文件中需要声明该变量.如果 ...

  9. 19. 从零开始编写一个类nginx工具, 配置数据的热更新原理及实现

    wmproxy wmproxy是由Rust编写,已实现http/https代理,socks5代理, 反向代理,静态文件服务器,内网穿透,配置热更新等, 后续将实现websocket代理等,同时会将实现 ...

  10. 7z 一键压缩备份

    该批处理已开源 开原地址: 点击进入 磁盘备份 工具有很多,如果你需要增量式备份的话,以下这些方法并不适合你.goodsync 可以了解一下. 以下方式仅适用于,懒人一键压缩备份. 对于我来说 定期的 ...