1 Star 0 Fork 11

coder_lw / wiki

forked from deepinwiki / wiki 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
sed 行处理.md 3.42 KB
一键复制 编辑 原始数据 按行查看 历史
htqx 提交于 2023-07-23 13:25 . 排版格式

sed 行处理工具

前言

在 linux 的世界中,shell 是很重要的一环。而 shell 脚本经常处理的内容是文本。sed 作为一个文本处理的好手,很多时候可以派上用场。

sed 和 awk、grep 并称文本处理三剑客:

  1. sed:擅长行处理(流)
  2. grep:擅长查找匹配
  3. awk:全功能,可编程,擅长列处理,数据分析

大多数情况,sed 一次处理一行,但支持对一行多次编辑。因此应该形成一个概念模型,1.流特性;2.一次读取一行,操作的都是针对某一行。某些操作,它是跨行的,即和 \n 换行符相关,这时就不能用到简单的 sed 命令了。

但是,sed 也是可以多行处理的,只是那样就很繁琐了,尽量使用更强大的工具,如 awk。

如何理解流的特性,如果一个文件有 500 行,它实际上是将你指定的命令操作,都依次在这 500 行运行一次,谨记这点。

单行处理

sed 语法格式: sed [选项] 命令 文件

  1. 原样输出,默认
  2. -n :匹配输出
  3. -r :扩展正则表达式
  4. 命令:
    1. p: 打印
    2. d:删除
    3. a:追加
    4. i:插入
    5. c:替换
    6. s:按模式替换,支持正则表达式
  5. 范围:命令前可以指定作用的行
    1. 1,$: 第一行到结尾
    2. 1~2:第一行开始,每两行选中一行(即1、3、5...)
    3. 1!: 不是第一行
    4. 1{p;d}: 等于 1 d; 1 d,即对里面的每一个子命令限定范围
    5. /str/: 正则匹配范围

实例:

# 原文是一个多行文本,所以 sed 会执行三次
# 用限定范围/bbb/,让子命令只在匹配的时候执行一次
# s 命令使用正则表达式替换内容为 xxx
# p 命令输出当前范围的内容,即原本的bbb,已经修改为 xxx
# 所以最终结果 xxx
echo -e "aaa\nbbb\nccc" |sed -n "/bbb/{s/bbb/xxx/g;p}"

多行处理

命令:

  1. h: 存储替换到临时空间(保持空间)
  2. H: 添加到临时空间
  3. g: 从临时空间读取并替换(模式空间)
  4. G:读取并追加
  5. x:交换二者
  6. -i : 直接修改原文

sed 概念,当前工作的空间叫模式空间 (pattern space),而临时空间叫保持空间。sed 工作的时候不改变原文,而只在模式空间工作。除非你指定 -i 参数,将直接改变原文。

sed 工作的流程是,读取一行到模式空间,接着处理,然后删除模式空间的内容,并读取第二行。因此,无论如何,它都无法同时处理两行数据。除非读取两行的内容到模式空间。

例子:

# 一次性读取所有行
# 我们这里是想将a\nb 替换为 ab,因为跨行了,所以单行模式处理不了
# 先把所有行写入保持空间,然后读取到模式空间(相当于合并了所有行)
# 1h 第一行覆盖保持空间内容
# 1!h 非第一行追加到保持空间
# 为何不用 1,$ H 或者 H,因为默认保持空间有个空行(我们不需要)。
# ${} 最后一行时,内容已经完全合并到保持空间,我们执行实际的操作
# ${g; ...} 读取内容到模式空间,替换掉当前内容(即ccc)
# ${...s/a\nb/ab/g...} 因为合并了,所以可以进行多行替换
# ${...p} 输出当前行内容,注意子命令都被 $ 范围限定的,理解这点很关键
echo -e "aaa\nbbb\nccc" |sed -n '1h;1!H;${g;s/a\nb/ab/g;p}

参考

  1. sed入门详解教程: https://www.cnblogs.com/liwei0526vip/p/5644163.html
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/coder_lw/wiki.git
git@gitee.com:coder_lw/wiki.git
coder_lw
wiki
wiki
master

搜索帮助

Bbcd6f05 5694891 0cc6727d 5694891