Skip to content

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 编辑操作,先替换 foobar,然后删除第二行。
-i直接修改文件sed -i 's/foo/bar/g' file.txt直接在文件 file.txt 中进行全局替换 foobar,而不是输出到标准输出。
-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(删除)dsed '2d' file.txt删除文件 file.txt 中的第二行。
p(打印)psed -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 替换为 Ab 替换为 Bc 替换为 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 文件中全局替换 oldtextnewtext
打印文件的某一行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.
  1. 使用 -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.
  2. 使用 -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.
  3. 使用 -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.
  4. 使用 -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.
  5. 使用 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.
  6. 使用 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!
  7. 使用 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.
  8. 使用 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.
  9. 使用 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.
  10. 使用 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.
  11. 使用 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.
  12. 使用 & 符号引用匹配部分。

    • 在所有出现的 "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:输出顺序为:第三组(最后一个单词)、第二组(中间部分)、第一组(第一个单词)。