05 行文本处理器 - sed
sed三个字母是英文 Steam EDitor 的缩写,意为流编辑器。其作用,主要是对文本进行编辑和转换。- 它可以从文件或标准输入读取内容,然后按照指定的规则进行替换、删除、插入、追加等操作,最终输出结果到屏幕或指定文件中。
sed指令常用于批量处理文本文件,例如修改配置文件、替换文本中的某些字符等。sed指令可以灵活地搭配正则表达式,提高文本处理的效率和精度。
sed 是一个功能强大的流编辑器,用于在 Linux 和 Unix 系统中进行文本处理。sed 是 "stream editor" 的缩写,它能以非交互的方式处理和转换文本。下面详细介绍 sed 的各个方面。
基本语法
bash
sed [options] 'command' file(s)- options:用于控制
sed的行为,如-e表示要执行的命令,-i表示在原文件上进行修改等。 - command:具体的
sed命令,用于指定文本处理的操作。 - file(s):要处理的文件,可以是一个或多个。
常用选项
| 选项 | 说明 | 示例 | 解释 |
|---|---|---|---|
-n | 静默模式 | sed -n '2p' file.txt | 在静默模式下,仅打印匹配的行,默认情况下 sed 会打印每一行。 |
-e | 多点编辑 | sed -e 's/foo/bar/' -e '2d' file.txt | 允许在同一命令中执行多个 sed 编辑操作,先替换 foo 为 bar,然后删除第二行。 |
-i | 直接修改文件 | sed -i 's/foo/bar/g' file.txt | 直接在文件 file.txt 中进行全局替换 foo 为 bar,而不是输出到标准输出。 |
-r | 使用扩展正则表达式 | sed -r 's/(foo)(bar)/\2\1/g' file.txt | 使用扩展正则表达式来匹配和替换文本,此示例将 foobar 替换为 barfoo。 |
常用命令
| 命令 | 格式 | 示例 | 说明 |
|---|---|---|---|
| s(替换) | s/查找模式/替换内容/标志 | sed 's/foo/bar/' file.txt | 将文件 file.txt 中的第一个 foo 替换为 bar。标志包括:g(全局替换)i(忽略大小写) |
| d(删除) | d | sed '2d' file.txt | 删除文件 file.txt 中的第二行。 |
| p(打印) | p | sed -n '2p' file.txt | 仅打印文件 file.txt 中的第二行。 |
| a(追加) | a\ 要追加的文本 | sed '2a\This is an appended line.' file.txt | 在文件 file.txt 的第二行后追加文本。 |
| i(插入) | i\ 要插入的文本 | sed '2i\This is an inserted line.' file.txt | 在文件 file.txt 的第二行前插入文本。 |
| c(改变) | c\ 新文本 | sed '2c\This is the new line.' file.txt | 将文件 file.txt 的第二行替换为新文本。 |
| y(字符替换) | y/源字符集/目标字符集/ | sed 'y/abc/ABC/' file.txt | 将文件 file.txt 中的 a 替换为 A,b 替换为 B,c 替换为 C。 |
sed 的语法
| 命令 | 解释 |
|---|---|
sed --help | 查看 sed 指令的帮助信息。 |
sed --version | 查看 sed 的版本信息。 |
sed '[line number]a\[string]' [filename] | 在文件的第 N 行后添加特定字符串 string。 |
sed '[line number]i\[string]' [filename] | 在文件的第 N 行前添加特定字符串 string。 |
sed '[line number]d' [filename] | 删除文件的第 N 行内容。 |
sed -n '[line number]p' [filename] | 打印文件的第 N 行内容。 |
sed '[line number]c\[string]' [filename] | 将文件的第 N 行内容替换为 string。 |
sed 's/str_a/str_b/' [filename] | 将文件中的字符串 str_a 替换为 str_b,每行只替换第一个匹配的字符串。 |
sed 's/str_a/str_b/g' [filename] | 将文件中的所有 str_a 字符串替换为 str_b。 |
sed '/[regex]/d' [filename] | 根据正则表达式 [regex] 过滤文件内容,并删除匹配的行。 |
sed '/[regex]/{s/str_a/str_b/g}' [filename] | 按照正则表达式 [regex] 过滤文件内容后,将匹配的行中的所有 str_a 替换为 str_b。 |
sed -i [sed command] [filename] | 直接在原始文件中进行替换,而不产生副本。 |
| `cat [filename] | sed [command]` |
高级用法
地址范围
可以指定一个地址范围,对该范围内的行进行操作。
bash
sed '1,3d' file # 删除第1到第3行
sed '2,$d' file # 删除第2行到文件末尾的所有行正则表达式
sed 支持基本的正则表达式和扩展的正则表达式(使用 -r 选项)。
bash
sed -r 's/[0-9]+/number/' file # 将所有数字替换为 'number'保存结果到新文件
可以将 sed 的输出重定向到一个新文件。
bash
sed 's/hello/world/' input.txt > output.txt替换特定行范围内的内容
bash
sed '2,4s/foo/bar/' input.txt # 只替换第 2 行到第 4 行中的 foo 为 bar使用 & 符号引用匹配部分
bash
sed 's/[0-9][0-9]*/& &/' file # 将所有数字加倍示例
常见用法
| 操作 | 命令 | 说明 |
|---|---|---|
| 删除空行 | sed '/^$/d' file | 删除文件 file 中的所有空行。 |
| 删除注释行 | sed '/^#/d' file | 删除文件 file 中所有以 # 开头的注释行。 |
| 批量替换多个文件中的内容 | sed -i 's/oldtext/newtext/g' *.txt | 在当前目录下所有 .txt 文件中全局替换 oldtext 为 newtext。 |
| 打印文件的某一行 | sed -n '5p' file | 仅打印文件 file 的第 5 行。 |
| 打印特定模式匹配的行 | sed -n '/pattern/p' file | 打印文件 file 中包含特定模式 pattern 的所有行。 |
简单示例
bash
➜ ~ nvim sed_test.txt
➜ ~ cat sed_test.txt
Line 1: Hello, World!
Line 2: sed is a stream editor.
Line 3: This is a simple text file.
Line 4: Learning sed is fun.
Line 5: Replace, delete, and print lines.
Line 6: sed has many powerful features.
Line 7: Practice makes perfect.
Line 8: Regular expressions are powerful.使用
-n选项抑制默认输出,p命令用于打印特定行。bash➜ ~ sed '2p' sed_test.txt Line 1: Hello, World! Line 2: sed is a stream editor. Line 2: sed is a stream editor. Line 3: This is a simple text file. Line 4: Learning sed is fun. Line 5: Replace, delete, and print lines. Line 6: sed has many powerful features. Line 7: Practice makes perfect. Line 8: Regular expressions are powerful. ➜ ~ sed -n '2p' sed_test.txt # 仅打印第 2 行内容 Line 2: sed is a stream editor.使用
-e选项允许在同一sed命令中执行多个编辑操作。bash➜ ~ sed -e 's/sed/SED/' -e '3d' sed_test.txt # 将 sed 替换为 SED 并删除第 3 行 Line 1: Hello, World! Line 2: SED is a stream editor. Line 4: Learning SED is fun. Line 5: Replace, delete, and print lines. Line 6: SED has many powerful features. Line 7: Practice makes perfect. Line 8: Regular expressions are powerful.使用
-i选项在原文件中进行编辑,而不是输出到终端。bash➜ ~ sed -i.bak '4s/Learning/Studying/' sed_test.txt # 将第 4 行中的 Learning 替换为 Studying,并创建备份文件 sed_test.txt.bak ➜ ~ sed -n '3p' sed_test.txt Line 3: This is a simple text file. ➜ ~ sed -n '3p' sed_test.txt.bak Line 3: This is a simple text file.使用
-r选项启用扩展正则表达式。bash➜ ~ sed -r 's/(Line [0-9]+):/HEADER:/' sed_test.txt # 将行号替换为 HEADER: HEADER: Hello, World! HEADER: sed is a stream editor. HEADER: This is a simple text file. HEADER: Studying sed is fun. HEADER: Replace, delete, and print lines. HEADER: sed has many powerful features. HEADER: Practice makes perfect. HEADER: Regular expressions are powerful.使用
s/old/new/g命令将每一行中的所有匹配替换为新字符串。bash➜ ~ sed -e 's/sed/SED/g' -e '3s/line/LINE/i' sed_test.txt # 将 sed 替换为 SED,并将第 3 行中的 line 替换为 LINE(忽略大小写) Line 1: Hello, World! Line 2: SED is a stream editor. LINE 3: This is a simple text file. Line 4: Studying SED is fun. Line 5: Replace, delete, and print lines. Line 6: SED has many powerful features. Line 7: Practice makes perfect. Line 8: Regular expressions are powerful. ➜ ~ sed -n '2,6p' sed_test.txt # 打印第 2 行到第 6 行 Line 2: sed is a stream editor. Line 3: This is a simple text file. Line 4: Studying sed is fun. Line 5: Replace, delete, and print lines. Line 6: sed has many powerful features.使用
d命令用于删除指定的行。bash➜ ~ sed '5d' sed_test.txt # 删除第 5 行 Line 1: Hello, World! Line 2: sed is a stream editor. Line 3: This is a simple text file. Line 4: Studying sed is fun. Line 6: sed has many powerful features. Line 7: Practice makes perfect. Line 8: Regular expressions are powerful. ➜ ~ sed '2,$d' sed_test.txt # 删除第 2 行到最后一行 Line 1: Hello, World!使用
p命令用于打印指定的行。bash➜ ~ sed -n '3p' sed_test.txt # 打印第 3 行 Line 3: This is a simple text file. ➜ ~ sed -n '3,$p' sed_test.txt # 打印第 3 行到最后一行 Line 3: This is a simple text file. Line 4: Studying sed is fun. Line 5: Replace, delete, and print lines. Line 6: sed has many powerful features. Line 7: Practice makes perfect. Line 8: Regular expressions are powerful.使用
a\text命令在指定行后添加新行。bash➜ ~ sed '7a\Added Line' sed_test.txt # 在第 7 行后添加新行 Line 1: Hello, World! Line 2: sed is a stream editor. Line 3: This is a simple text file. Line 4: Studying sed is fun. Line 5: Replace, delete, and print lines. Line 6: sed has many powerful features. Line 7: Practice makes perfect. Added Line Line 8: Regular expressions are powerful.使用
i\text命令在指定行前插入新行。bash➜ ~ sed '3i\Inserted Line' sed_test.txt # 在第 3 行前插入新行 Line 1: Hello, World! Line 2: sed is a stream editor. Inserted Line Line 3: This is a simple text file. Line 4: Studying sed is fun. Line 5: Replace, delete, and print lines. Line 6: sed has many powerful features. Line 7: Practice makes perfect. Line 8: Regular expressions are powerful.使用
c\text命令用于替换指定行的内容。bash➜ ~ sed '2c\Changed Line' sed_test.txt # 替换第 2 行的内容 Line 1: Hello, World! Changed Line Line 3: This is a simple text file. Line 4: Studying sed is fun. Line 5: Replace, delete, and print lines. Line 6: sed has many powerful features. Line 7: Practice makes perfect. Line 8: Regular expressions are powerful.使用
y命令用于字符转换。bash➜ ~ sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' sed_test.txt # 将所有小写字母转换为大写字母 LINE 1: HELLO, WORLD! LINE 2: SED IS A STREAM EDITOR. LINE 3: THIS IS A SIMPLE TEXT FILE. LINE 4: STUDYING SED IS FUN. LINE 5: REPLACE, DELETE, AND PRINT LINES. LINE 6: SED HAS MANY POWERFUL FEATURES. LINE 7: PRACTICE MAKES PERFECT. LINE 8: REGULAR EXPRESSIONS ARE POWERFUL.使用
&符号引用匹配部分。在所有出现的 "sed" 字符串前后添加方括号
[]bash➜ ~ sed 's/sed/[&]/g' sed_test.txt # 在所有出现的 "sed" 字符串前后添加方括号 Line 1: Hello, World! Line 2: [sed] is a stream editor. Line 3: This is a simple text file. Line 4: Studying [sed] is fun. Line 5: Replace, delete, and print lines. Line 6: [sed] has many powerful features. Line 7: Practice makes perfect. Line 8: Regular expressions are powerful.在匹配的单词前后添加字符
bash➜ ~ sed 's/Line [0-9]\+/(&)/' sed_test.txt # 在匹配的单词前后添加小括号 (Line 1): Hello, World! (Line 2): sed is a stream editor. (Line 3): This is a simple text file. (Line 4): Studying sed is fun. (Line 5): Replace, delete, and print lines. (Line 6): sed has many powerful features. (Line 7): Practice makes perfect. (Line 8): Regular expressions are powerful. ➜ ~ sed '2,6s/Line [0-9]\+/#&/' sed_test.txt # 在 2-6 行匹配的单词前后添加井号 Line 1: Hello, World! #Line 2: sed is a stream editor. #Line 3: This is a simple text file. #Line 4: Studying sed is fun. #Line 5: Replace, delete, and print lines. #Line 6: sed has many powerful features. Line 7: Practice makes perfect. Line 8: Regular expressions are powerful.在匹配部分中间插入字符
bash➜ ~ sed -e 's/Hello/H&!/' -n -e '1p' sed_test.txt # 将 "Hello" 替换为 "HHello!" Line 1: HHello!, World!重复匹配的部分
bash➜ ~ sed '1,3s/Line [0-9]\+/#(& &)/' sed_test.txt # 将 1-3 行匹配的部分重复两次 #(Line 1 Line 1): Hello, World! #(Line 2 Line 2): sed is a stream editor. #(Line 3 Line 3): This is a simple text file. Line 4: Studying sed is fun. Line 5: Replace, delete, and print lines. Line 6: sed has many powerful features. Line 7: Practice makes perfect. Line 8: Regular expressions are powerful.在匹配部分前后添加额外内容
bash➜ ~ sed 's/^/#Start: &/' sed_test.txt | sed 's/$/& #End/' # 在每行的开头和结尾添加额外内容 #Start: Line 1: Hello, World! #End #Start: Line 2: sed is a stream editor. #End #Start: Line 3: This is a simple text file. #End #Start: Line 4: Studying sed is fun. #End #Start: Line 5: Replace, delete, and print lines. #End #Start: Line 6: sed has many powerful features. #End #Start: Line 7: Practice makes perfect. #End #Start: Line 8: Regular expressions are powerful. #End ➜ ~ sed -e '5,$s/^/#Start: &/' -e '1,3s/$/& #End/' sed_test.txt # 在 5-最后一行开头添加额外内容,在 1-3 行结尾添加额外内容 Line 1: Hello, World! #End Line 2: sed is a stream editor. #End Line 3: This is a simple text file. #End Line 4: Studying sed is fun. #Start: Line 5: Replace, delete, and print lines. #Start: Line 6: sed has many powerful features. #Start: Line 7: Practice makes perfect. #Start: Line 8: Regular expressions are powerful.修改并保留原始文本
bash➜ ~ sed 's/.*/& -> &/' sed_test.txt | sed 's/\(.*\) -> \(.*\)/\1 -> \2/' | sed -E 's/(.+)/echo "\1" | rev/e' # 将每行文本反转并保留原始文本 !dlroW ,olleH :1 eniL >- !dlroW ,olleH :1 eniL .rotide maerts a si des :2 eniL >- .rotide maerts a si des :2 eniL .elif txet elpmis a si sihT :3 eniL >- .elif txet elpmis a si sihT :3 eniL .nuf si des gniydutS :4 eniL >- .nuf si des gniydutS :4 eniL .senil tnirp dna ,eteled ,ecalpeR :5 eniL >- .senil tnirp dna ,eteled ,ecalpeR :5 eniL .serutaef lufrewop ynam sah des :6 eniL >- .serutaef lufrewop ynam sah des :6 eniL .tcefrep sekam ecitcarP :7 eniL >- .tcefrep sekam ecitcarP :7 eniL .lufrewop era snoisserpxe ralugeR :8 eniL >- .lufrewop era snoisserpxe ralugeR :8 eniL ➜ ~ sed -n -e '1,3p' -e '1,3s/.*/& -> &/' sed_test.txt | sed -E 's/(.+)/echo "\1" | rev/e' !dlroW ,olleH :1 eniL .rotide maerts a si des :2 eniL .elif txet elpmis a si sihT :3 eniL # sed 's/.*/& -> &/' sed_test.txt:将每行内容转换为 原内容 -> 原内容。 # sed -E 's/(.+)/echo "\1" | rev/e':执行 rev 命令来翻转每一行的内容,并输出为 原内容 -> 翻转后的内容。sed 's/.*/& -> &/' sed_test.txt:将每一行内容复制一份,并在中间加上->,形成原内容 -> 原内容的形式。sed 's/\(.*\) -> \(.*\)/\1 -> \2/':这一步其实没有做任何修改,因为\1 -> \2只是将原内容 -> 原内容的形式再次匹配并保留,和第一步的结果是一样的。sed -E 's/(.+)/echo "\1" | rev/e':通过使用rev命令将内容翻转。rev是一个外部工具,可以将输入的字符串反转。echo "\1" | rev生成的命令用于将sed匹配的内容进行翻转。/e表示执行替换命令的结果。
在匹配的内容前后添加标签
bash➜ ~ sed 's/.*sed.*/<TAG>&<\/TAG>/' sed_test.txt # 在匹配的 "sed" 的行前后添加标签 Line 1: Hello, World! <TAG>Line 2: sed is a stream editor.</TAG> Line 3: This is a simple text file. <TAG>Line 4: Studying sed is fun.</TAG> Line 5: Replace, delete, and print lines. <TAG>Line 6: sed has many powerful features.</TAG> Line 7: Practice makes perfect. Line 8: Regular expressions are powerful.组合引用多个匹配的部分
bash➜ ~ sed -E '1,3s/^([[:alpha:]]+)(.*[[:space:]])([[:alpha:]]+)[[:punct:]]?$/\3\2\1/' sed_test.txt # 将 1-3 行的首尾单词互换位置 World 1: Hello, Line editor 2: sed is a stream Line file 3: This is a simple text Line Line 4: Studying sed is fun. Line 5: Replace, delete, and print lines. Line 6: sed has many powerful features. Line 7: Practice makes perfect. Line 8: Regular expressions are powerful.^([[:alpha:]]+):匹配行首的第一个单词,并将其捕获为第一组(\1)。(.*[[:space:]]):匹配中间部分的任意字符(包括空格),并将最后的空白字符一起捕获为第二组(\2),确保最后一个单词与中间部分正确分离。([[:alpha:]]+)[[:punct:]]?$:匹配行尾的最后一个单词,并将其捕获为第三组(\3)。还考虑到行尾可能带有标点符号。\3\2\1:输出顺序为:第三组(最后一个单词)、第二组(中间部分)、第一组(第一个单词)。