Sed 是一个非交互式的[1] 流编辑器。 它接收文本输入,无论是来自stdin还是来自文件,对输入的指定行执行特定操作,一次一行,然后将结果输出到stdout或文件。 在 shell 脚本中,sed 通常是管道中几个工具组件之一。
Sed 根据传递给它的地址范围确定要操作输入中的哪些行。[2] 可以通过行号或要匹配的模式指定此地址范围。 例如,3d表示 sed 删除输入的第 3 行,并且/Windows/d告诉 sed 您希望删除输入中包含与 "Windows" 匹配的每一行。
在 sed 工具包的所有操作中,我们将主要关注三个最常用的操作。 它们是打印(到stdoutstdout),删除和替换。
表 C-1. 基本的 sed 操作符
操作符 | 名称 | 效果 |
---|---|---|
[地址范围]/p | 打印 | 打印 [指定的地址范围] |
[地址范围]/d | 删除 | 删除 [指定的地址范围] |
s/pattern1/pattern2/ | 替换 | 将 pattern2 替换为行中 pattern1 的第一个实例 |
[地址范围]/s/pattern1/pattern2/ | 替换 | 在地址范围内,将 pattern2 替换为行中 pattern1 的第一个实例 |
[地址范围]/y/pattern1/pattern2/ | 转换 | 在地址范围内,将 pattern2 替换为行中 pattern1 的第一个实例内,将 pattern1 中的任何字符替换为 pattern2 中的相应字符(等同于 tr) |
[地址] i pattern Filename | 插入 | 在文件 Filename 中指示的地址处插入 pattern。 通常与-i 原地选项一起使用。 |
g | 全局 | 对输入中每个匹配行的每个模式匹配进行操作 |
![]() | 除非将g(全局)操作符附加到 substitute 命令,否则替换仅对每行中模式匹配的第一个实例进行操作。 |
从命令行和 shell 脚本中,sed 操作可能需要引用和某些选项。
sed -e '/^$/d' $filename # The -e option causes the next string to be interpreted as an editing instruction. # (If passing only a single instruction to sed, the "-e" is optional.) # The "strong" quotes ('') protect the RE characters in the instruction #+ from reinterpretation as special characters by the body of the script. # (This reserves RE expansion of the instruction for sed.) # # Operates on the text contained in file $filename. |
在某些情况下,sed 编辑命令将无法与单引号一起使用。
filename=file1.txt pattern=BEGIN sed "/^$pattern/d" "$filename" # Works as specified. # sed '/^$pattern/d' "$filename" has unexpected results. # In this instance, with strong quoting (' ... '), #+ "$pattern" will not expand to "BEGIN". |
![]() | Sed 使用-e选项来指定以下字符串是指令或一组指令。 如果字符串中仅包含单个指令,则可以省略此选项。 |
sed -n '/xzy/p' $filename # The -n option tells sed to print only those lines matching the pattern. # Otherwise all input lines would print. # The -e option not necessary here since there is only a single editing instruction. |
表 C-2. sed 操作符示例
表示法 | 效果 |
---|---|
8d | 删除输入的第 8 行。 |
/^$/d | 删除所有空白行。 |
1,/^$/d | 从输入开头删除到第一个空白行(包括第一个空白行)。 |
/Jones/p | 仅打印包含 "Jones" 的行(使用 -n 选项)。 |
s/Windows/Linux/ | 将 "Linux" 替换为每行输入中找到的 "Windows" 的第一个实例。 |
s/BSOD/stability/g | 将 "stability" 替换为每行输入中找到的 "BSOD" 的每个实例。 |
s/ *$// | 删除每行末尾的所有空格。 |
s/00*/0/g | 将所有连续的零序列压缩为单个零。 |
echo "Working on it." | sed -e '1i How far are you along?' | 打印 “How far are you along?” 作为第一行,“Working on it” 作为第二行。 |
5i 'Linux is great.' file.txt | 在 file.txt 文件的第 5 行插入 ‘Linux is great.’。 |
/GUI/d | 删除所有包含 "GUI" 的行。 |
s/GUI//g | 删除 "GUI" 的所有实例,保留每行其余部分不变。 |
将零长度字符串替换为另一个字符串等同于删除输入行中的该字符串。 这将保留该行其余部分不变。 应用s/GUI//到行
The most important parts of any application are its GUI and sound effects |
The most important parts of any application are its and sound effects |
反斜杠强制 sed 替换命令继续到下一行。 这具有使用第一行末尾的换行符作为替换字符串的效果。
s/^ */\ /g |
地址范围后跟一个或多个操作可能需要使用花括号括起来,并带有适当的换行符。
/[0-9A-Za-z]/,/^$/{ /^$/d } |
![]() | 快速将文本文件加倍行距的方法是sed G filename. |
有关 shell 脚本中 sed 的示例,请参阅
有关 sed 的更深入处理,请参阅 参考书目 中的相关参考资料。
[1] | Sed 在没有用户干预的情况下执行。 |
[2] | 如果未指定地址范围,则默认值为所有行。 |