linux 三剑客 - 文本编辑命令 sed
linux 提供了强大的文本分析工具,如 grep
, sed
, awk
,号称三剑客。本篇介绍文本编辑命令 sed
。
sed
(stream editor,流编辑器)命令能够通过模式匹配(如正则表达式)对指定的行进行编辑文本内容。默认在所有 linux 发行版中都预装该命令。
sed
处理文本以行为单位,处理时将当前行存储到临时缓冲区(称为模式空间 “pattern space”),然后 sed
对缓冲区的内容执行动作进行文本编辑,处理完成后将缓冲区的内容送往屏幕,接着处理下一行,直至文件末尾。默认不修改原文件内容,不过可以指定命令参数(如 -i)将修改后的内容重定向输出。
基本命令格式
1 | sed [options] '[addr]command[flags]' filename |
示例:
1 | # -e 是 options,表示直接在命令行上进行编辑,默认选项,不指定其他选项默认就是该选项 |
options
options 是 sed
命令作用于整个文档的全局范围,注意与 flags 的区别,flags 针对 addr 作用在具体的行上,执行 command 动作。
options | 含义 |
---|---|
-e | 直接在命令行上进行文本编辑,默认选项 |
-f sed-filenme | 从 sed-filename 中读取 sed 动作,如果动作过多,那么可以写入文件内,-f 直接从文件中读取动作 |
-i | 直接修改文件内容。即 sed 将编辑后的文本内容重定向覆盖存储到原文件 |
-n | 只打印模式匹配到的行。如果不指定,会把文件所有内容打印到屏幕 |
-r | 支持扩展正则表达式 |
addr
addr 就是行号,不指定时表示所有行,即整个文档。
1 | # 指定所有行。缺省时表示匹配整个文档所有行 |
flags
flags 表示针对指定的行执行动作,如全局替换、只替换 1 个、删除、打印等。
flags | 含义 |
---|---|
g | 表示行内全面替换: sed -i "1,3s/xxx/yyy/g" hello.py |
p | 表示打印行,默认会打印所有文档内容。常和 -n 参数一起使用,表示只打印匹配的行:sed -n "1,$s/xxx/p" hello.py |
d | 表示删除匹配的内容:sed '4,$/^#/d' hello.py 表示从第 4 行到文档结尾删除以 # 开头的行 |
i | 表示在匹配的内容前添加,类似于 vim 的 i:sed '3i there are insert words' hello.py 表示在第 3 行前增加一行内容 “there are insert words” |
a | 表示在匹配的内容后添加,类似于 vim 的 a:sed '3a there are insert words\ there are another insert line' hello.py 表示在第 3 行后增加两行内容 |
c | 表示替换某行内容:sed '3c This is changed line' hello.py ,表示替换第 3 行内容为:”This is changed line”. 匹配替换:sed '/xjz/c author is jinzhongxu' hello.py 表示把 hello.py 中包含 xjz 的行替换为 jinzhongxu |
y | 表示转换,如 sed 'y/123/456/' hello.py 表示把 hello.py 中的 1 转写为 4, 2 转写为 5, 3 转写为 6 |
w | 表示把匹配的行写入到新文件中,新文件不存在时会自动创建:sed '1w hello.txt' hello.py 把 hello.py 的第一行写入到 hello.txt 中;sed -n '/mail/w hello.txt' hello.py 把 hello.py 中包含 mail 的行覆盖写入到 hello.txt |
r | 把其他文件的内容插入到文件指定的行:sed '3r hello.txt' hello.py 把 hello.txt 的内容插入到 hello.py 的第 3 行后;sed '1~1r a.txt' test.txt 在每一行的后面插入 a.txt; sed '1~2r a.txt' test.txt 在奇数行的后面插入 a.txt; sed '/z/r a.txt' test.txt 在匹配 z 的行后面插入 a.txt |
q | 退出脚本:sed '2q' hello.py 只打印 hello.py 的第 2 行,然后退出; sed '/root/{s/bash/zsh/;q}' /etc/passwd 把匹配到 root 的第一个匹配的行的 bash 替换为 zsh,然后退出 |
示例:
1 | # 多个命令用大括号 |
参考文献
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 J. Xu!
评论