在Linux操作系统中,grep、sed、awk被称为文本操作"三剑客",上一期中,我们将详细介绍grep的基本使用方法,希望能够帮助到有需要的朋友,现在,我们继续学习sed。
我会参考官方文档来做翻译理解。下面正式开始:
sed(Stream Editor) 命令,翻译为:流编辑器 。它主要用于文本替换、查找和替换,以及其他文本操作,例如插入、删除和搜索。使用sed
,我们可以在不打开整个文件的情况下编辑文件内容。它还支持正则表达式,使其成为更强大的文本操作工具。
虽然 sed 在某些方面类似于允许脚本编辑的编辑器(例如 ed),但它通过只对输入进行一次遍历来工作,因此效率更高。然而,sed 真正与其他类型的编辑器区别之处在于它可以在管道中过滤文本的能力。
GNU sed 主页: GNU sed - GNU Project - Free Software Foundation
GNU 软件通用帮助: Getting help with GNU software- GNU Project - Free Software Foundation
下面是关于 sed 命令的详细介绍,包括参数、用法和示例代码。
1.sed 命令详解(中文)
语法
sed [选项]... {脚本(仅在没有其他脚本时)} [输入文件]...
参数选项
bash
-n, --quiet, --silent
抑制模式空间的自动打印
-e script, --expression=script
将脚本添加到要执行的命令中
-f script-file, --file=script-file
将脚本文件的内容添加到要执行的命令中
--follow-symlinks
原地处理时跟踪符号链接
-i[后缀], --in-place[=后缀]
原地编辑文件(如果提供了后缀,则会进行备份)
-c, --copy
在 -i 模式下对文件进行改组时使用复制而不是重命名
-b, --binary
不执行任何操作;用于与 WIN32/CYGWIN/MSDOS/EMX 兼容(以二进制模式打开文件(CR+LF 不被特殊处理))
-l N, --line-length=N
指定 l 命令所需的行包装长度
--posix
禁用所有 GNU 扩展。
-r, --regexp-extended
在脚本中使用扩展正则表达式。
-s, --separate
将文件视为单独的文件,而不是单个连续的长流。
-u, --unbuffered
从输入文件中加载少量数据,并更频繁地刷新输出缓冲区
-z, --null-data
用空字符 (NUL) 分隔行
--help
显示此帮助并退出
--version
输出版本信息并退出
如果没有给出 **-e
, --expression
, -f
, 或 --file
**选项,则第一个非选项参数将被视为要解释的 sed 脚本。所有剩余的 аргумент (yìrgēn) 都将被视为输入文件名;如果没有指定输入文件,则读取标准输入。
2.sed 命令语法概要(中文)
这仅仅是 sed 命令的简要语法概要,旨在为已经熟悉 sed 的用户提供提醒。有关更完整的描述,请查阅其他文档(例如 texinfo 文档)。
零地址"命令"
bash
Zero-address ``commands''
: label 用于 b 和 t 命令的标签。
# comment 注释一直持续到下一个换行符(或 -e 脚本片段的末尾)。
} {} 代码块的结束括号。
零地址或单地址命令
bash
= 打印当前行号。
a \
文本 追加文本,其中每个嵌入的新行都以反斜杠开头。
i \
文本 插入文本,其中每个嵌入的新行都以反斜杠开头。
q [退出代码]
立即退出 sed 脚本,不再处理任何输入,除非禁用了自动打印,否则将打印当前模式空间。退出代码参数是 GNU 扩展。
Q [退出代码]
立即退出 sed 脚本,不再处理任何输入。这是 GNU 扩展。
r 文件名 追加从 filename 读取的文本。
R 文件名 追加从 filename 读取的一行。每次调用该命令都会从文件中读取一行。这是 GNU 扩展。
接受地址范围的命令
bash
{ 开始一个命令块(以 } 结束)。
b label 跳转到标签;如果省略标签,则跳转到脚本末尾。
c \
text 用文本替换选定的行,其中每个嵌入的新行都以反斜杠开头。
d 删除模式空间。开始下一个循环。
D 如果模式空间不包含换行符,则启动一个标准的新循环,就像发出 d 命令一样。否则,删除模式空间中的文本直到第一个换行符,并使用结果模式空间重新启动循环,而不读取新的输入行。
h H 将模式空间复制/追加到保持空间。
g G 将保持空间复制/追加到模式空间。
l 以"视觉上明确"的形式列出当前行。
l width 以"视觉上明确"的形式列出当前行,并将其按宽度字符进行拆分。这是 GNU 扩展。
n N 将下一行输入读入/追加到模式空间。
p 打印当前模式空间。
P 打印当前模式空间的第一个嵌入式换行符之前的内容。
s/regexp/replacement/
尝试将 regexp 与模式空间匹配。如果匹配成功,则用 replacement 替换匹配到的部分。replacement 可以包含特殊字符 & 来引用模式空间中匹配到的部分,以及特殊转义序列 \1 到 \9 来引用 regexp 中相应的匹配子表达式。
t label
如果自上次读取输入行和上次 t 或 T 命令以来,s/// 执行了成功的替换,则跳转到标签;如果省略标签,则跳转到脚本末尾。
T label
如果自上次读取输入行和上次 t 或 T 命令以来,没有 s/// 执行成功的替换,则跳转到标签;如果省略标签,则跳转到脚本末尾。这是 GNU 扩展。
w filename 将当前模式空间写入 filename。
W filename 将当前模式空间的第一行写入 filename。这是 GNU 扩展。
x 交换保持空间和模式空间的内容。
y/source/dest/ 将模式空间中出现在源中的字符转换为目标中对应的字符。
3、常用选项和示例
下面是关于sed
的一些常见用法和示例代码:
bash
# 显示文件的部分文本:
# 可以只查看文件的一部分,例如只打印22到29行的内容。
sed -n 22,29p testfile.txt
# 显示除某些行之外的所有行:
# 显示除22到29行之外的所有行。
sed 22,29d testfile.txt
# 显示从第n行开始的每m行:
# 可以显示从第2行开始的每3行内容。
sed -n '2~3p' file.txt
# 删除一行:
# 可以删除指定行号的行。
sed Nd testfile.txt
# 若要删除文件的最后一行
sed $d testfile.txt。
# 查找和替换:
# 首次替换:将文件中的"danger"替换为"safety"。
sed 's/danger/safety/' testfile.txt
# 全局替换:可以完全替换文件中的所有"danger"。
sed 's/danger/safety/g' testfile.txt
# 替换特定行上的字符串:
# 替换文件第4行的字符串
sed '4 s/danger/safety/' testfile.txt
# 替换文件第4到9行的字符串
sed '4,9 s/danger/safety/' testfile.txt
# 在匹配搜索之后或之前添加一行:
# 使用选项a,在每个模式匹配之后添加新行
sed '/danger/a "This is new line with text after match"' testfile.txt
# 使用选项i,在每个模式匹配之前添加新行
sed '/danger/i "This is new line with text before match" ' testfile.txt
# 运行多个sed命令:
# 如果需要执行多个sed表达式,可以使用选项-e将sed命令链接起来
sed -e 's/danger/safety/g' -e 's/hate/love/' testfile.txt
# 在编辑文件之前进行备份:
# 使用选项-i.bak,sed会在编辑文件之前创建一个备份文件,以防止意外修改导致的数据丢失
sed -i.bak -e 's/danger/safety/g' testfile.txt
# 删除以模式开头和结尾的文件行:
# 删除以特定字符串开始并以另一个字符串结束的行
sed -e 's/^danger.*stops$//g' testfile.txt
# 附加行:
# 在每行之前添加一些内容
sed -e 's/.*/testing sed &/' testfile.txt
# 删除所有注释行和空行
sed -e 's/#.*//;/^$/d' testfile.txt
# 从/etc/passwd文件获取所有用户名:
# 获取/etc/passwd文件的所有用户名列表
sed 's/\\([^:]*\\).*/\\1/' /etc/passwd
# 防止覆盖系统链接:
使用-i参数时,为了避免破坏链接,请使用follow-symklinks选项
sed -i --follow-symlinks 's/danger/safety/g' testfile.txt
这些示例应该能帮助你更好地理解 sed 命令的用法和功能。先写这多吧,主要还是要多练习,练习的话,用子系统Ubuntu就可以。继续关注我,下期讲讲述awk命令!
如果您觉得有些用处,欢迎在评论区留言,关注。谢谢您的阅读!
往期学习笔记: