1. sed命令简介
sed
(stream editor)是一个强大的文本处理工具,用于对文本流或文件进行过滤和转换。它主要用于自动编辑一个或多个文件;简化对文件的重复操作;编写转换程序等。其语法格式为:
sed [OPTION]... {script-only-if-no-other-script} [input-file]...
其中可选选项([OPTION]部分)包括:
-n, --quiet, --silent 抑制自动打印模式空间 --debug 注释程序执行 -e script, --expression=script 将脚本添加到要执行的命令中 -f script-file, --file=script-file 将脚本文件的内容添加到要执行的命令中 --follow-symlinks 处理时跟随符号链接 -i[SUFFIX], --in-place[=SUFFIX] 就地编辑文件(如果提供了后缀,则制作备份) -l N, --line-length=N 指定 `l' 命令的期望换行长度 --posix 禁用所有 GNU 扩展 -E, -r, --regexp-extended 在脚本中使用扩展正则表达式(为便于移植,请使用 POSIX -E)。 -s, --separate 将文件视为独立的而不是单一的连续长流。 --sandbox 在沙盒模式下操作(禁用 e/r/w 命令)。 -u, --unbuffered 从输入文件加载最少量的数据并更频繁地刷新输出缓冲区 -z, --null-data 以 NUL 字符分隔行 --help 显示此帮助信息并退出 --version 输出版本信息并退出
如果没有指定 -e
、--expression
、-f
或 --file
选项,则第一个非选项参数将被视为要解释的 sed
脚本。所有剩余的参数都是输入文件的名称;如果没有指定输入文件,则读取标准输入。
2. 实际运用举例
2.1 删除文本中的空白行
sed '/^$/d' file.txt
这个命令会显示 file.txt 中所有非空行,不修改原文件。其中,使用正则表达式^$
匹配空行,即开始和结束之间没有任何字符的行。d 命令用于删除匹配的行。
2.2 文本替换:将所有出现的 “apple” 替换为 “orange”
sed 's/apple/orange/g' file.txt
这个命令会显示替换后的内容,不修改原文件。其中:
s
表示替换操作。apple
是要查找的文本。orange
是替换后的文本。g
表示全局替换,即替换每一行中的所有匹配项。
例如当前目录有一个file.text文件为:
执行该命令后输出结果为:
可见,文档中所有的“apple”都被替换成了“orange”
2.3 在每行的末尾添加文本
sed 's/$/ end of line/' file.txt
这个命令会在每行的末尾添加 " end of line" 文本,它将显示修改后的内容,不会修改原文件。其中:
$
在正则表达式中表示行的末尾。
例如当前目录有一个file.text文件为:
执行该命令后输出结果为:
2.4 打印文件的一些行
sed -n '2,6p' file.txt
这个示例的命令用于显示第 2 行到第 6行的内容。其中:
-n
选项与p
命令一起使用,用于抑制自动打印并只打印指定的行。2,6
指定了行范围。
例如当前目录有一个file.text文件为:
执行该命令后输出结果为:
这不会修改原文件。
2.5 将文件中的所有数字增加 1
sed 's/[0-9]/&1/g' file.txt
这个命令会在每个数字后面添加 1,如 8 变为 81,显示修改后的内容,不修改原文件。其中:
- 正则
[0-9]
匹配任何单个数字; &
代表匹配到的整个部分(这里是单个数字);&1
表示在匹配到的数字后添加 1;
例如有一个file.text文件为:
执行该命令后的结果为:
这不会改变原文件的内容。
2.6 注释掉包含特定文本的行
sed '/apple$/s/^/#/' file.txt
这个命令会在所有包含 “pattern” 的行前添加 #,显示修改后的内容打印,不修改原文件。其中:
- 正则
/apple$/
查找包含以 “apple” 结尾的行。 s/^/#/
将这些行的开始替换为 “#”,即添加注释。
例如有一个file.text文件为:
执行该命令后的结果为:
可见,由于第1行、第3行以“apple”结尾,输出的内容中这两行前面添加了一个“#”号。
2.7 删除文件中的最后一行
sed '$d' file.txt
这个命令会删除 file.txt 的最后一行,显示修改后的内容,不修改原文件。其中:
$
表示文件的最后一行。d
是删除命令。
例如有一个file.text文件为:
执行该命令后的结果为:
2.8 将文件中的第一行移动到最后一行
sed '1h;1d;$G' file.txt
这个命令会将第一行移动到文件的最后,显示修改后的内容,不修改原文件。其中:
1h
表示将第一行复制到暂存缓冲区。1d
表示删除第一行。$G
表示在文件的最后一行后追加暂存缓冲区的内容。
例如有一个file.text文件为:
执行该命令后的结果为:
3. 就地编辑
之前给出的示例都不会直接修改文件,但是很多时候我们是希望直接修改文件的。就地编辑是 sed
命令的一个非常有用的功能,允许直接修改文件而不是仅仅输出修改后的结果。这通过 -i
选项实现,可以选择性地指定一个后缀来创建原文件的备份。
3.1 就地编辑示例
例如假设有一个名为 example.txt
的文件,内容如下:
Hello, this is a test file. This file contains some sample text. We will replace the word 'sample' with 'example'.
执行命令:
sed -i 's/sample/example/g' example.txt
这里:
-i
:表示“就地编辑”,即直接修改原文件而不是输出到标准输出。s
:表示替换操作。g
:表示全局替换,即在整个文件中进行替换,而不仅仅是每行的第一个匹配项。
修改后的 example.txt
文件内容将变为:
Hello, this is a test file. This file contains some example text. We will replace the word 'example' with 'example'.
可见最后一行的’sample’变成了’example’。
3.2 创建备份并就地编辑
如果你想在修改文件的同时创建一个备份,可以在 -i
选项后添加一个后缀。这个后缀将被用作备份文件的扩展名。
sed -i.bak 's/old_text/new_text/g' file.txt
这个命令不仅会修改 file.txt
,还会创建一个名为 file.txt.bak
的备份文件,其中包含原始内容。
继续使用上面的 example.txt
文件:
Hello, this is a test file. This file contains some sample text. We will replace the word 'sample' with 'example'.
执行命令:
sed -i.bak 's/example/sample/g' example.txt
这将把文件中的 “example” 替换回 “sample”,并创建一个包含修改前内容的备份文件 example.txt.bak
。其中:
-i.bak
:表示“就地编辑”,并指定 .bak
作为备份文件的后缀。这意味着在修改原文件之前,sed
会先将原文件 example.txt
复制一份,命名为 example.txt.bak
。
s
:表示替换操作。example
:这是要被替换的文本模式,即查找文本中所有出现的 “example”。sample
:这是替换后的文本,即将找到的 “example” 替换为 “sample”。g
:表示全局替换,即在整个文件中进行替换,而不仅仅是每行的第一个匹配项。
修改后的 example.txt
文件内容将变为:
Hello, this is a test file. This file contains some sample text. We will replace the word 'sample' with 'sample'.
备份文件 example.txt.bak
的内容为:
Hello, this is a test file. This file contains some example text. We will replace the word 'example' with 'example'.
4. 结论与应用
sed 是一个极其强大的流编辑器,它允许我们通过简单的命令行操作来执行复杂的文本处理任务。无论是进行简单的文本替换、删除特定行、还是更复杂的文本操作,sed 都能提供高效且灵活的解决方案。通过上述示例,我们可以看到 sed 在处理各种文本编辑任务时的实用性和便捷性。
自动化处理:sed
可以用于脚本中,自动化处理大量文件,减少重复劳动。例如,编写一个Dockerfile时,我们可以使用sed来完成文本就地编辑工作:
RUN sed -i 's/# DBPassword=/DBPassword=zabbix/g' /etc/zabbix/zabbix_server.conf
其中:
-i
:这个选项告诉sed
直接修改文件,而不是输出修改后的内容到标准输出。这称为“就地编辑”;'s/# DBPassword=/DBPassword=zabbix/g'
:这是一个sed
的替换命令,具体包含以下部分:s
:表示进行替换操作。# DBPassword=
:这是要被替换的文本模式,即查找以# DBPassword=
开头的文本。这通常表示该行是被注释的。- DBPassword=zabbix
:这是替换后的文本,即将找到的文本替换为
DBPassword=zabbix。这个操作实际上是取消注释并设置数据库密码为
zabbix`; g
:表示全局替换,即在整个文件中进行替换,而不仅仅是每行的第一个匹配项。
/etc/zabbix/zabbix_server.conf
:这是要修改的文件路径。
- 文本分析:可以快速修改或提取文件中的数据,对于日志分析、数据抽取等场景尤为有用。
- 编程辅助:对源代码进行批量修改,如批量添加注释、修改变量名等。