文字处理-sed

sed 是非常常用的流式处理编辑工具,配合正则表达式可以进行十分效率的文字处理。它通过逐行地将文字读取,暂存进模式空间,通过指定的命令进行处理后,输出至标准输出,直到文件或者说输入的结束。原理十分简单,来学习一下吧。

命令格式

sed [选项及参数]… ‘操作命令’ 文件…

常用选项

  • -n 静默模式 取消 sed 默认的输出
  • -e 多重编辑 可以多次使用,携带 sed 命令作为该选项的参数,对于缓冲区的每一行按命令顺序进行处理
  • -f 使用 sed 操作的脚本处理,跟上脚本文件名做参数。sed 脚本可以保存多条 sed 命令,一行一条,依次执行。
  • -r 使用拓展正则,类似 grep -e 或者 egrep 的增强,让人少些一点转义符
  • -i 原地修改,该选项会使得 sed 命令直接修改原文件,可以紧跟一个后缀如 -i.bk,同时生成备份

命令组成

sed 命令的组成通常是 ‘行选择具体操作’。sed 在读入行内容之后,如果匹配定址要求就会进行命令操作。我们来两部分分开一看~

行选择

  • num 选择第 num 行。
  • start,end 选择第 start 行至第 end 行。
  • start~step 从 start 行开始,以 step 为步长选择行。
  • /pattern/ 选择含有该正则的内容的行。
  • start,/pattern/ 从 start 行开始直到首次成功匹配表达式的一行将被选定,注意 sed 的处理机制,如果表达式最终无法有任何匹配行,将会对 start 行之后的所有行进行选定。
  • /pattern/,end 从首次成功匹配表达式的一行至 end 行将被选定,如果在第 end 行之前如果没有成功匹配将会不有行被选中。
  • ! 置于行选择末尾,进行反选,如 10,20! 将排除 10 至 20 行。

具体操作

  • p 打印缓冲内容,通常配合 -n 选项测试指令正确性。
  • q 提前退出 sed,当到达匹配行或者指定行就退出 sed。
  • i\[content] 行前追加内容,如在第 1 行至第 5 行,每行之后插入‘===’:'1,5i\==='
  • a\[content] 行后追加内容。
  • c\[content] 替换内容,如果是批量选择,并不是对每行内容进行替换,而是对整体替换成相应内容。
  • d 删除。
  • s/pattern/new_chars/[g] 对选定的行中首次匹配表达式的内容替换成目标字符串,如果末尾使用‘g’,可以对行中所有匹配内容替换。
  • y/old-char-set/new-char-set 对选定行中所有 old-char-set 内的字符替换成相应的新的字符。
  • n 提前读取下一输入行至缓冲区。
  • r [file-name] 行后追加指定文件内容。
  • w [file-name] 将选定行输入至指定文件。
  • h 复制匹配行进入暂存空间。
  • G 配合 h 命令,取出暂存空间内的行,插入至模式空间的末尾。
  • x 配合 h 命令,交换当前匹配行的暂存空间内的行。

命令叠加

需要多次使用 sed 操作的时候,可以有这么些办法:

  1. 通过 {命令1;命令2...} 可以使用‘{}’将多个命令整合一块儿,中间使用‘;’分割,类似代码块的表达。其中如果如果多个命令的行定位条件一致,可以将该部分提出,如:'{10p;10p}' 等于 '10{p;p}'
  2. 通过 -e 选项多次输入 sed 命令。
  3. 将多个 sed 命令逐行写入文件,使用 -f 选项执行 sed。

额外技巧

sed 命令其实和正则表达式通常配合使用,所以这一些小技巧其实和正则有很密切的关系。比如对于一个简单的替换操作,如 s/abc/xyz/ 是十分简单的,但是 sed 支持更复杂的操作,可以用一些特殊意义的操作符号:

  • & 表示正则匹配成功的原字符串内容,如想要替换所有数字为它的百倍,可以使用 ‘s/[[:digit:]]\+/&00/g’
  • \num 获取缓存的匹配中缓存的字符串,num 指定位置(这取决于表达式中使用了多少次小括号‘()’)。
    • 如去除数字并字母大写,’s/([[:digit:]]\+\)\|\([[:alpha:]]\+\)/\U\2/gp’
    • 获取包含一段 ip 的文本中 ip 的前两段地址 ‘s/\([0-9]\+\):\([0-9]\+\):[0-9]\+:[0-9]+/\1 \2/p’
  • \u 将后方的表达式结果进行首字母大写处理
  • \U 将后方的表达式结果进行大写处理
  • \l 将后方的表达式结果进行首字母小写处理
  • \L 将后方的表达式结果进行小写处理
码路加油