温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

sed4.4手册

发布时间:2020-08-08 10:26:07 来源:ITPUB博客 阅读:149 作者:85579711 栏目:建站服务器

sed,流编辑器

目录

  • 1简介
  • 2运行sed
    • 2.1概述
    • 2.2命令行选项
    • 2.3退出状态
  • 3sed脚本
    • 3.1 sed脚本概述
    • 3.2 sed命令摘要
    • 3.3 s命令
    • 3.4常用命令
    • 3.5较少使用的命令
    • 3.6 sed大师命令
    • 3.7特定于GNU的命令 sed
    • 3.8多种命令语法
      • 3.8.1需要换行符的命令
  • 4地址:选择行
    • 4.1地址概述
    • 4.2按数字选择行
    • 4.3通过文本匹配选择行
    • 4.4范围地址
  • 5正则表达式:选择文本
    • 5.1正则表达式概述 sed
    • 5.2基本(BRE)和扩展(ERE)正则表达式
    • 5.3基本正则表达式语法概述
    • 5.4扩展正则表达式语法概述
    • 5.5字符类和括号表达式
    • 5.6正则表达式扩展
    • 5.7反向引用和子表达式
    • 5.8转义序列 - 指定特殊字符
    • 5.9语言环境注意事项
  • 6高级sed:循环和缓冲区
    • 6.1 sed工作原理
    • 6.2保持和模式缓冲区
    • 6.3多线技术 - 使用D,G,H,N,P来处理多条线
    • 6.4分支和流量控制
      • 6.4.1分支和周期
      • 6.4.2分支示例:连线
  • 7一些示例脚本
    • 7.1连线
    • 7.2中心线
    • 7.3增加数字
    • 7.4将文件重命名为小写
    • 7.5打印bash环境
    • 7.6线的反转字符
    • 7.7跨多行的文本搜索
    • 7.8线长调整
    • 7.9文件的反向行
    • 7.10编号
    • 7.11编号非空行
    • 7.12计数字符
    • 7.13计数单词
    • 7.14计数线
    • 7.15打印第一行
    • 7.16打印最后一行
    • 7.17使重复行独特
    • 7.18打印输入的重复行
    • 7.19删除所有重复的行
    • 7.20挤压空白线
  • GNU sed的限制和不受限制
  • 9其他资源学习关于 sed
  • 10报告错误
  • 附录A GNU自由文件许可证
  • 概念指数
  • 命令和选项索引

GNU sed

该文件记录GNU 版本4.4 sed,一个流编辑器。

版权所有©1998-2017自由软件基金会

授权根据GNU自由文件许可证1.3版或自由软件基金会发布的任何更新版本的条款复制,分发和/或修改本文档; 没有不变的部分,没有封面文本,也没有封底文本。许可证的副本包含在题为“GNU自由文件许可证”的部分。


1简介

sed是一个流编辑器。流编辑器用于对输入流(文件或流水线的输入)执行基本文本转换。虽然在某些方面类似于允许脚本编辑(例如ed) 的编辑器,sed只能通过输入一次,但效率更高。但是,它有sed能力在管道中过滤文本,特别区别于其他类型的编辑器。



2运行sed

本章介绍如何运行sedsed 脚本和单个sed命令的详细信息将在下一章讨论。


2.1概述

通常sed被这样调用:

sed SCRIPT INPUTFILE ... 

例如,要取代所有出现的“你好' 至 '世界'在文件中 input.txt中

sed / s / hello / world /'input.txt> output.txt 

如果不指定INPUTFILE,或者如果INPUTFILE - , sed过滤标准输入的内容。以下命令是等效的:

sed / s / hello / world /'input.txt> output.txt  sed's / hello / world /' output.txt  cat input.txt | sed / s / hello / world /' - > output.txt 

sed将输出写入标准输出。使用-一世在现场编辑文件而不是打印到标准输出。又见Ws///w写入输出到其它文件的命令。以下命令修改file.txt的 并且不产生任何输出:

sed -i / hello / world'file.txt 

默认情况下sed打印所有已处理的输入(除了通过命令修改/删除的输入d)。使用-n抑制输出,以及p打印特定行命令。以下命令仅打印输入文件的第45行:

sed -n'45p'file.txt 

sed将多个输入文件视为一个长流。以下示例打印第一个文件的第一行(此时就把one.txt存盘)和最后一个文件的最后一行(three.txt)。使用-s 以扭转这种行为。

sed -n'1p; $ p'one.txt two.txt three.txt 

没有 -e 要么 -F选项,sed使用第一个非选项参数作为脚本,以及以下非选项参数作为输入文件。如果-e 要么 -F选项用于指定脚本,所有非选项参数均作为输入文件。选项-e和 -F可以组合,并且可以出现多次(在这种情况下,最终的有效脚本将连接所有单个脚本)。

以下示例是等效的:

sed'/ hello / world /'input.txt> output.txt   sed -e's / hello / world  /'input.txt > output.txt sed --expression ='s / hello / world /'input.txt > output.txt   echo's / hello / world /'> myscript.sed  sed -f myscript.sed input.txt> output.txt  sed --file = myscript.sed input.txt> output.txt 

2.2命令行选项

调用的完整格式sed是:

sed选项... [SCRIPT] [INPUTFILE ...] 

sed 可以使用以下命令行选项调用:

--version

打印sed正在运行的版本和版权声明,然后退出。

--help

打印使用消息,简要总结这些命令行选项和错误报告地址,然后退出。

-n --quiet --silent

默认情况下,sed通过脚本在每个循环结束时打印出图案空间(请参阅如何sed工作)。这些选项禁用此自动打印,并且sed仅在通过p命令明确告知时才产生输出

-e script --expression=script

脚本中的命令添加到要处理输入时要运行的命令集。

-f script-file --file=script-file

将文件脚本文件中包含的命令添加 到要处理输入时要运行的命令集。

-i[SUFFIX] --in-place[=SUFFIX]

此选项指定要在现场编辑文件。 GNU sed通过创建临时文件并将输出发送到此文件而不是标准输出。1

这个选项意味着 -s

当文件结束到达时,临时文件将重命名为输出文件的原始名称。扩展名(如果提供)用于在重命名临时文件之前修改旧文件的名称,从而备份副本2)。


该规则遵循:如果扩展名不包含a *,则作为后缀添加到当前文件名的末尾; 如果扩展名包含一个或多个* 字符,则每个星号将替换为当前文件名。这允许您为备份文件添加前缀,而不是(或除了)后缀,甚至将原始文件的备份副本放置到另一个目录中(如果目录已存在)。

如果没有提供扩展名,原始文件将被覆盖而不进行备份。

-l N --line-length=N

指定命令的默认换行长度l长度为零(零)意味着永远不要缠绕长线。如果未指定,则取为70。

--posix

GNU sed包括POSIX sed的几个扩展名为了简化写入便携式脚本,此选项将禁用此手册所有文档的扩展名,包括其他命令。 大多数扩展sed程序都接受POSIX所规定的语法之外的程序,但其中一些(例如Reporting Bugs中N描述命令的行为)实际上违反了标准。如果要仅禁用后一种扩展名,则可以将该变量设置为非空值。 POSIXLY_CORRECT

-b --binary

此选项在每个平台上可用,但仅在操作系统区分文本文件和二进制文件之间才有效。当进行这样的区分时,如MS-DOS,Windows的情况,Cygwin文本文件由由回车符换行字符分隔的行组成 ,并且sed看不到结尾的CR。当指定此选项时,sed将以二进制模式打开输入文件,因此不要求此特殊处理,并考虑以行结尾的行。

--follow-symlinks

此选项仅在支持符号链接的平台上可用,并且仅在选项时才有效果 -一世 被指定。在这种情况下,如果在命令行中指定的文件是符号链接,sed则将跟随链接并编辑链接的最终目的地。默认行为是中断符号链接,以使链接目的地不被修改。

-E -r --regexp-extended

使用扩展正则表达式而不是基本正则表达式。扩展的正则表达式是那些 egrep接受的; 它们可以更清晰,因为它们通常具有较少的反斜杠。历史上这是一个GNU扩展,但是-E 扩展已经被添加到POSIX标准(http://austingroupbugs.net/view.php?id=528),所以使用 -E为了便携性。GNU sed已经接受了-E 作为多年来的无证选项,* BSD seds已经接受 -E 多年以来,但使用的脚本 -E可能不会移植到其他旧系统。扩展正则表达式

-s --separate

默认情况下,sed会将命令行上指定的文件视为单个连续的长流。GNU sed 扩展允许用户将它们视为单独的文件:范围地址(如“/ ABC /,/ DEF /')不允许跨越多个文件,行号相对于每个文件的开始,$指的是每个文件的最后一行,并且从R命令调用的文件在每个文件的开头都被重绕。

--sandbox

在沙箱模式下, e/w/r命令被拒绝 - 包含它们的程序将被中止而不运行。沙箱模式确保sed 仅在命令行上指定的输入文件上运行,并且无法运行外部程序。

-u --unbuffered

缓冲输入和输出尽可能最低限度。(如果输入来自“尾巴',您希望尽快看到转换后的输出。)

-z --null-data --zero-terminated

将输入视为一组行,每行以零字节(ASCII'NUL'字符)而不是换行符。此选项可用于命令,如'-z'和'find -print0'来处理任意的文件名。

如果不 -e, -F, - 表达, 要么 - 文件 选项在命令行中给出,则命令行上的第一个非选项参数被视为要执行脚本

如果在处理上述内容后仍有任何命令行参数,这些参数将被解释为要处理的输入文件的名称。 文件名“ - '指标准输入流。如果没有指定文件名,将处理标准输入。



2.3退出状态

退出状态为零表示成功,非零值表示失败。GNU sed返回以下退出状态错误值:

0

成功完成

1

无效的命令,无效的语法,无效的正则表达式或与之一起使用的 GNU sed扩展命令--posix

2

在命令行上指定的一个或多个输入文件无法打开(例如,如果找不到文件或拒绝读取权限)。处理继续与其他文件。

4

I / O错误或运行时严重的处理错误, GNU sed立即中止。

另外,该命令qQ可用于终止 sed与自定义退出代码值(这是一个GNU sed扩展名):

$ echo | sed'Q42'; echo $? 42 


3个sed脚本


3.1 sed脚本概述

sed程序由一个或多个的sed命令,由一个或多个的传递 -e, -F, - 表达,和 - 文件 选项或第一个非选项参数,如果使用这些选项的零。本文将参考“the” sed脚本; 这被理解为意味着传入的所有脚本脚本文件顺序连接。请参阅概述

sed 命令遵循以下语法:

[addr] X [选项] 

X是单字母sed命令。 [addr]是可选的行地址。如果[addr]指定,则命令X将仅在匹配的行上执行。 [addr]可以是单行号,正则表达式或行范围(请参见sed地址)。额外[options]的用于某些sed命令。

以下示例删除输入中的行30到35。 30,35是地址范围。d是delete命令:

sed '30,35d'input.txt> output.txt 

以下示例打印所有输入,直到以“FOO'被发现。如果找到这样的行, sed将以退出状态42终止。如果没有找到这样的行(并且没有其他错误发生),sed 将退出状态0. /^foo/是一个正则表达式地址。 q是退出命令。42是命令选项。

sed'/ ^ foo / q42'input.txt> output.txt 

一个内的命令脚本脚本文件可以由分号(分离;)或换行符(ASCII 10)。可以指定多个脚本-e 要么 -F 选项。

以下示例都是等效的。他们执行两个sed 操作:删除与正则表达式匹配的任何行/^foo/,并替换字符串的所有出现“你好'与'世界“:

sed'/ ^ foo / d; s / hello / world /'input.txt> output.txt   sed -e'/ ^ foo / d'-e's / hello / world /'input.txt> output.txt   echo'/ ^ foo / d'> script.sed  echo's / hello / world /'>> script.sed  sed -f script.sed input.txt> output.txt   echo'/ hello / world /'> script2.sed  sed -e'/ ^ foo / d'-f script2.sed input.txt> output.txt 

命令aci,由于它们的语法,不能被随后工作作为命令分隔符分号,因此应当用换行被终止或者被放置在的末端脚本脚本文件命令之前也可以带有可选的非空白字符。请参阅多命令语法



3.2 sed命令摘要

GNU 支持以下命令sed一些是标准的POSIX命令,而另外一些是GNU扩展。每个命令的详细信息和示例如下。(助记符)显示在括号中。

a\ text

在一行后附加文本

a text

在一行之后附加文本(替代语法)。

b label

无条件分配标签标签可以被省略,在这种情况下,在下一个周期开始。

c\ text

文本替换(更改)行

c text

文本替换(更改)行(替代语法)。

d

删除图案空间; 马上开始下一个循环。

D

如果模式空间包含换行符,则删除直到第一个换行符的模式空间中的文本,并重新启动循环与结果模式空间,而不会读取新的输入行。

如果模式空间不包含换行符,则会像d执行命令一样启动正常的新循环

e

执行在模式空间中找到的命令,并使用输出替换模式空间; 尾随的换行被压制。

e command

执行命令并将其输出发送到输出流。该命令可以跨多行运行,除了最后一行之外,还有一个反斜杠。

F

(filename)打印当前输入文件的文件名(带尾随的换行符)。

g

使用保持空间的内容替换图案空间的内容。

G

在图案空间的内容中附加换行符,然后将保留空间的内容附加到模式空间的内容。

h

(保持)用图案空间的内容替换保持空间的内容。

H

在保留空间的内容中附加换行符,然后将模式空间的内容附加到保留空间的内容。

i\ text

在一行之前插入文字

i text

在一行之前插入文本(替代语法)。

l

以明确的形式打印图案空间。

n

(接下来)如果自动打印未被禁用,请打印图案空间,然后,无论如何将图案空间替换为下一行输入。如果没有更多的输入,则sed退出而不处理任何命令。

N

向模式空间添加换行符,然后将下一行输入追加到模式空间。如果没有更多的输入,则sed退出而不处理任何命令。

p

打印图案空间。

P

打印图案空间,直到第一个。

q[exit-code]

(退出)退出sed而不处理任何命令或输入。

Q[exit-code]

(退出)此命令q与图形空间的内容相同,但不会打印。q一样,它提供了返回一个退出代码给调用者的功能。

r filename

读取文本文件一个文件。例:

R filename

在当前周期结束时或当读取下一个输入行时,将一行文件名排队读取并插入到输出流中。

s/regexp/replacement/[flags]

(替换)将正则表达式与模式空间的内容进行匹配。如果找到了,更换匹配的字符串 替换

t label

(测试)分支到标签,只有当s自上一条输入行被读取或条件分支以来已成功 执行时,才能进行标记标签可以被省略,在这种情况下,在下一个周期开始。

T label

(测试)只有当自上次输入行被读取或条件分支以来没有成功的 ubstitut 分支,才能进行标签s标签可以被省略,在这种情况下,在下一个周期开始。

v [version]

(版本)此命令不执行任何操作,但sed如果 不支持GNU sed扩展,或者所请求的版本不可用,则会失败。

w filename

将模式空间写入文件名

W filename

将给定的文件名写入到第一个换行符的模式空间的部分

x

交换保留和模式空格的内容。

y/src/dst/

将与任何源字符匹配的模式空间中的任何字符dest-chars中的相应字符进行音译

z

(zap)此命令清空模式空间的内容。

#

一个评论,直到下一个换行符。

{ cmd ; cmd ... }

组合几个命令。

=

打印当前输入行号(带有尾随的换行符)。

: label

指定的位置的标签为分支命令(b, tT)。


3.3 s命令

s命令(如替代)可能是最重要的sed,有很多不同的选择。s命令的语法是's / regexp / replacement / flags”。

它的基本概念很简单:该s命令尝试将模式空间与提供的正则表达式regexp匹配如果匹配成功,则匹配的模式空间的那部分被替换替换

有关regexp语法的详细信息,请参阅正则表达式地址

所述替换可以包含?是一个从1到9,包括端点)的引用,这指的是包含在之间的匹配的所述部分?个 及其匹配此外,替换可以包含 引用模式空间的整个匹配部分的未转义字符。 \n\(\)&

/ 字符可通过任何给定的内的任何其他单个字符被均匀地取代s命令。/ 字符(或任何其他字符代替它使用)可以在出现正则表达式替换 仅当它是由前面\的字符。

最后,作为一个GNU sed扩展,可以包括由一个反斜杠和一个字母的特殊序列 LlUu,或E其含义如下:

\L

将替换为小写,直到找到\U\E找到,

\l

将下一个字符转成小写,

\U

将替换成大写,直到找到\L\E找到,

\u

将下一个字符转成大写字母,

\E

停止案件转换由\L开始\U

g标志被使用时,情况转换不会从正常表达式的一个出现传播到另一个。例如,当执行以下命令时,AB-'在图案空间:

S / \(B \ \?) -  / X \ U \ 1 /克 

输出为'axxB”。当更换第一个' - ',''序列只影响'\ 1”。它不影响x更换时被添加到模式空间字符b-xB

在另一方面,\l并且\u做影响了替换文本的其余部分,如果他们之后是一个空的替代。随着'AB-'在模式空间中,以下命令:

S / \(B \ \?) -  / \ U \ 1X /克 

将取代“ - '与'X'(大写)和'B-'与'BX”。如果这种行为是不希望的,你可以通过添加一个“。\ E'序后'\ 1' 在这种情况下。

要包括文字\&或在最终替换换行符,一定要早于期望的\&或换行的置换\

s命令可以后跟零个或多个以下标志

g

将替换应用于所有匹配到正则表达式,而不仅仅是第一个。

number

只有更换届的匹配正则表达式


s指挥 相互作用注意:POSIX标准没有指定当您混合g数字修饰符时应该发生什么,并且目前在sed实现中没有广泛同意的含义对于GNU sed,交互定义为:在数字 th 之前忽略匹配,然后匹配并替换所有匹配的数字

p

如果进行替换,则打印新的图案空间。

注意:当指定选项pe选项时,两者的相对排序产生非常不同的结果。一般来说,ep(评估然后打印)是你想要的,但另一方面操作可能对调试是有用的。因此,当前版本的GNU sed特别解释p了前后选项的存在,e在评估之前和之后 打印模式空间,而一般来说,该s命令的标志只显示一次。尽管如此,这种行为可能会在将来的版本中发生变化。

w filename

如果进行替换,则将结果写入命名文件。作为GNU sed扩展,支持两个特殊的文件名的/ dev /标准错误,将结果写入标准错误,以及 的/ dev /标准输出,写入标准输出。3

e

该命令允许从shell命令将输入管道转换为模式空间。如果进行替换,则执行在模式空间中找到的命令,并将其空格替换为其输出。尾随的换行被压制; 如果要执行的命令包含NUL字符,则结果未定义这是一个GNU sed扩展。

I i

I正则表达式匹配修饰符是一个GNU 扩展,它使sed匹配正则表达式以不区分大小写的方式。

M m

M正则表达式匹配修饰符是GNU sed 扩展,它指示GNU sed多行模式下匹配正则表达式修饰符分别引起^$匹配换行符之后的空字符串(除正常行为之外),换行符之前的空字符串。有一些特殊的字符序列(\`\')始终与缓冲区的开头或结尾相匹配。另外,在多行模式下,句点字符与新行字符不匹配。


3.4常用命令

如果你完全使用sed,你很可能想知道这些命令。

#



#字符开头的注释; 评论将持续到下一个换行符。


如果您关心可移植性,请注意,某些实现sed(其不 符合POSIX的)可能仅支持单个单行注释,然后仅在脚本的第一个字符为a时才支持#


警告:如果sed脚本的前两个字符#n,那么-n(no-autoprint)选项被强制。如果您想在脚本的第一行发表评论,该评论以字母“?“你不想要这个行为,那么一定要用一个资本”?'或者在'?”。

q [exit-code]

退出sed而不处理任何命令或输入。

示例:打印第二行后停止:

$ seq 3 | sed 2q  1  2 

此命令只接受一个地址。请注意,如果没有禁用自动打印,则打印当前图案空间-n选项。sed脚本返回退出代码的功能GNU sed扩展。

另请参见GNU sed扩展Q命令,无需打印当前模式空间即可静默退出。

d

删除图案空间; 马上开始下一个循环。

示例:删除第二个输入行:

$ seq 3 | sed 2d  1  3 
p

打印图案空间(到标准输出)。此命令通常仅与该命令配合使用-n 命令行选项。

示例:仅打印第二个输入行:

$ seq 3 | sed -n 2p  2 
n

如果未禁用自动打印,请打印图案空间,然后,无论如何使用下一行输入替换图案空间。如果没有更多的输入,则sed退出而不处理任何命令。

该命令对于跳过线是有用的(例如,每第N行处理)。

示例:在每3行执行替换(即两个n命令跳过两行):

$ seq 6 | sed'n; n; s /./ x /'  1  2  x  4  5  x 

GNU sed提供的扩展地址语法第一?步骤 ,以实现相同的结果:

$ seq 6 | sed'0?3s /./ x /'  1  2  x  4  5  x 
{ commands }

一组命令可之间被封闭 {}字符。当您希望通过单个地址(或地址范围)匹配来触发一组命令时,这特别有用。

示例:执行替换然后打印第二个输入行:

$ seq 3 | sed -n'2 {s / 2 / X /; p}'  X 

3.5较少使用的命令

虽然可能比上一节更少使用,但是sed可以使用这些命令构建一些非常小的但有用的脚本。

y/source-chars/dest-chars/

将与任何源字符匹配的模式空间中的任何字符dest-chars中的相应字符进行音译

示例:音译'AJ'进'0-9“:

$ echo你好世界|  sed'y / abcdefghij / 0123456789 /' 74llo worl3 

/任何给定y命令中字符可以被任何其他单个字符均匀地替换。)

所述的实例/(或者任何其他字符代替它使用), \或换行符可以出现在源极-字符DEST-字符 列表,提供每个实例由逃脱\源极-字符DEST-字符列表必须 包含相同数量的字符(后脱逸出)。

有关tr类似的功能,请参阅GNU coreutils中命令。

a text

追加文本行之后。这是标准命令GNU扩展名a- 有关详细信息,请参见下文。

示例:添加“你好“第二行之后:

$ seq 3 | SED '2A你好'  1  2  3 

a命令之后的空白空白被忽略。要添加的文本被读取直到行尾。

a\ text

追加文本行之后。

示例:添加'你好'后第二行( - |表示打印输出行):

$ seq 3 | sed'2a \  hello'  -  | 1  -  | 2  -  | hello  -  | 3 

a命令将按照此命令(每个但最后一个结尾以及\从输出中删除的)命令排队,以在当前周期结束时或当读取下一个输入行时排队。


作为GNU扩展,此命令接受两个地址。

处理文本中的转义序列,因此您应该\\文本中使用打印单个反斜杠。

命令在最后一行之后恢复,而没有反斜杠(\) - '世界'在下面的例子中:

$ seq 3 | sed'2a \  hello \  world  3s /./ X /'  -  | 1  -  | 2  -  | hello  -  | world  -  | X 

作为GNU扩展,a命令和文本可以分为两个-e参数,使脚本更容易:

$ seq 3 | sed -e'2a \'-e hello  1  2  hello  3   $ sed -e'2a \'-e“$ VAR” 
i text

在一行之前插入文字这是标准命令GNU扩展名i- 有关详细信息,请参见下文。

示例:插入“你好“在第二行之前:

$ seq 3 | SED '2I你好'  1  你好 2  3 

i命令之后的空白空白被忽略。要添加的文本被读取直到行尾。

i\ text

立即输出跟随此命令的文本行。

示例:插入'你好'在第二行之前( - |表示打印输出行):

$ seq 3 | sed'2i \  hello'  -  | 1  -  | hello  -  | 2  -  | 3 

作为GNU扩展,此命令接受两个地址。

处理文本中的转义序列,因此您应该\\文本中使用打印单个反斜杠。

命令在最后一行之后恢复,而没有反斜杠(\) - '世界'在下面的例子中:

$ seq 3 | sed'2i \  hello \  world  s /./ X /'  -  | X  -  | hello  -  | world  -  | X  -  | X 

作为GNU扩展,i命令和文本可以分为两个-e参数,使脚本更容易:

$ seq 3 | sed -e'2i \'-e hello  1  hello  2  3   $ sed -e'2i \'-e“$ VAR” 
c text

文字代替行这是标准命令GNU扩展名c- 有关详细信息,请参见下文。

示例:将第2至第9行替换为“你好“:

$ seq 10 | SED '2,9c你好'  1只 10 

c命令之后的空白空白被忽略。要添加的文本被读取直到行尾。

c\ text

删除匹配地址或地址范围的行,并输出该命令后面的文本行。

示例:用第2至第4行替换“你好'和'世界'( - |表示打印输出行):

$ seq 5 | sed'2,4c \  hello \  world'  -  | 1  -  | hello  -  | world  -  | 5 

如果没有给出地址,则替换每一行。

此命令完成后,将启动一个新的循环,因为模式空间将被删除。在下面的示例中,c启动一个新的循环,替换文本不执行替换命令:

$ seq 3 | sed'2c \  hello  s /./ X /'  -  | X  -  | hello  -  | X 

作为GNU扩展,c命令和文本可以分为两个-e参数,使脚本更容易:

$ seq 3 | sed -e'2c \'-e hello  1  hello  3   $ sed -e'2c \'-e“$ VAR” 
=

打印当前的输入行号(带有尾随的换行符)。

$ printf'%s \ n'aaa bbb ccc | sed =  1  aaa  2  bbb  3  ccc 

作为GNU扩展,此命令接受两个地址。

l n

以明确的形式打印图案空间:不可打印的字符(和\字符)以C风格的转义格式打印; 长行被分割,尾随\字符表示分割; 每行的末尾都标有a $

n指定所需的换行长度; 长度为0(零)意味着永远不要缠绕长线。如果省略,则使用在命令行中指定的默认值。所述? 参数是一个GNU sed扩展。

r filename

读取文本文件一个文件。例:

$ seq 3 | SED '2R的/ etc /主机名称'  1  2  fencepost.gnu.org  3 

在当前周期结束时或当读取下一个输入行时,将要读取并插入到输出流中的文件名的内容排队请注意,如果无法读取文件名,则将其视为空文件,无任何错误指示。

作为GNU sed扩展,特殊值的/ dev /标准输入 支持文件名,其中读取标准输入的内容。


作为GNU扩展,此命令接受两个地址。然后将文件重新读取并插入到每个寻址行上。

w filename

将模式空间写入文件名作为GNU sed扩展,支持两个特殊的文件名的/ dev /标准错误,将结果写入标准错误,以及 的/ dev /标准输出,写入标准输出。4

在读取第一个输入行之前,将创建(或截断)该文件; 引用相同文件名的所有w命令(包括w成功s命令标志的实例)在 不关闭并重新打开文件的情况下输出。

D

如果模式空间不包含换行符,则会像d执行命令一样启动正常的新循环否则,删除图形空间中的文本直到第一个换行符,并重新启动循环与结果模式空间,而不读取新的输入行。

N

向模式空间添加换行符,然后将下一行输入追加到模式空间。如果没有更多的输入,则sed退出而不处理任何命令。

什么时候 -z 被使用,零字节(ascii'NUL'字符)添加在行之间(而不是新行)。

sed如果没有“下一个”输入行,默认情况下不会终止。这是可以禁用的GNU扩展--posix请参阅最后一行的N命令

P

将图案空间的部分打印到第一个换行符。

h

使用模式空间的内容替换保持空间的内容。

H

在保留空间的内容中附加换行符,然后将模式空间的内容附加到保留空间的内容。

g

使用保持空间的内容替换图案空间的内容。

G

在图案空间的内容中附加换行符,然后将保留空间的内容附加到模式空间的内容。

x

交换保留和模式空格的内容。


3.6 sed大师命令

在大多数情况下,使用这些命令表明,您可能更喜欢像awk Perl 这样的编程但偶尔有人坚持坚持sed,这些命令可以使一个人写一个非常复杂的脚本。

: label

[无地址]


指定分支命令标签位置在所有其他方面,无操作。

b label

无条件分支到标签标签可以被省略,在这种情况下,在下一个周期开始。

t label

只有当自上一条输入行被读取或有条件分支以来已成功执行ubstitution时,才能进行标记s标签可以被省略,在这种情况下,在下一个周期开始。


3.7特定于GNU的命令 sed

这些命令是特定于GNU的 sed,所以你必须小心使用它们,只有当你确定阻碍可移植性不是坏的时候。它们允许您检查GNU sed扩展或者经常需要执行的任务,但不支持标准sed

e [command]

该命令允许从shell命令将输入管道转换为模式空间。没有参数,e命令执行在模式空间中找到的命令,并用输出替换模式空间; 尾随的换行被压制。

如果指定了参数,则该e命令将其解释为命令,并将其输出发送到输出流。该命令可以跨多行运行,除了最后一行之外,还有一个反斜杠。

在这两种情况下,如果要执行的命令包含NUL字符,则结果是未定义的

请注意,与r命令不同,命令的输出将立即打印; r命令会将输出延迟到当前周期的结束。

F

打印当前输入文件的文件名(带尾随的换行符)。

Q [exit-code]

此命令只接受一个地址。


此命令q与图形空间的内容相同,但不会打印。q一样,它提供了返回一个退出代码给调用者的功能。

这个命令可以是有用的,因为完成这个显而易见的微不足道的功能的唯一替代方法是使用 -n 选项(这可能会使您的脚本不必要地复杂化)或使用以下代码片段,这样通过读取整个文件而浪费时间,而没有任何明显的效果:

:吃 $ d 在最后一行静静地退出 N 读另一行,默默地 g 每次覆盖模式空间以节省内存 b吃 
R filename

在当前周期结束时或当读取下一个输入行时,将一行文件名排队读取并插入到输出流中。请注意,如果无法读取文件名,或者如果文件名达不到,则不附加任何行,没有任何错误指示。

r命令一样,具有特殊的价值的/ dev /标准输入 对于从标准输入读取一行的文件名是受支持的。

T label

只有在自上次输入行被读取或有条件分支以来没有成功的 ubstitut时,才能进行标记s标签可以被省略,在这种情况下,在下一个周期开始。

v version

此命令不执行任何操作,但sed如果不支持GNU sed扩展,则会失败 ,因为其他版本sed不实现。另外,您可以指定sed脚本所需的版本,例如4.0.5默认是4.0 因为这是实现此命令的第一个版本。

此命令即使在环境中设置,可以启用所有GNU扩展 POSIXLY_CORRECT

W filename

将给定的文件名写入到第一个换行符的模式空间的部分。w关于文件处理命令下的一切都在这里。

z

此命令清空模式空间的内容。它通常与“小号/.*//',但是效率更高,并且在输入流中存在无效多字节序列的情况下起作用。 POSIX要求这样的序列匹配“',所以sed在大多数多字节语言环境(包括UTF-8语言环境)中,没有可移植的方式清除脚本中间的缓冲区。


3.8多种命令语法

sed 程序中指定多个命令有几种方法

从文件运行sed脚本时,使用换行符是最自然的(使用 -F 选项)。

在命令行中,所有sed命令可能被换行分隔。或者,您可以将每个命令指定为参数-e 选项:

$ seq 6 | SED '1D  3D  5D'  2  4  6   $ 6序列| sed -e 1d -e 3d -e 5d  2  4  6 

分号(';')可以用来分离最简单的命令:

$ seq 6 | SED '1D; 3D;图5d'  2  4  6 

{}btT:命令可以用分号分隔(这是一个非便携式GNU sed扩展名)。

$ seq 4 | sed'{1d; 3d}'  2  4   $ seq 6 | SED '{1D; 3D};图5d'  2  4  6 

在使用的标签btT:指令被读取,直到一个分号。领先和尾随的空白被忽略。在下面的例子中,标签是“X”。第一个例子与GNU一起使用 sed第二个是便携式的等价物。有关分支和标签的更多信息,请参阅分支和流控制

$ seq 3 | sed'/ 1 / bx; s / ^ / = /; :X ; 3D”  1  = 2   $ SEQ 3 | SED -e '/ 1 / BX' -e 'S / ^ / = /' -e ':X' -e '3D'  1  = 2 
3.8.1需要换行符的命令

以下命令不能用分号分隔,需要换行符:

aci(追加/变更/插入)

所有字符以下aci命令被作为追加/变更/插入的文本。使用分号会导致不良结果:

$ seq 2 | sed'1aHello; 2D”  1  您好; 2d  2 

使用命令分开 -e 或换行:

$ seq 2 | sed -e 1aHello -e 2d  1  Hello   $ seq 2 | SED '1aHello  2D'  1  你好 

请注意,指定要添加的文本('你好“)后aci本身就是一个GNU sed扩展。符合POSIX标准的便携式解决方案是:

$ seq 2 | SED '1A \  你好 2D'  1  你好 
# (评论)

所有字符“直到下一个换行符被忽略。

$ seq 3 | sed'#这是一个评论; 2D”  1  2  3   $ SEQ 3 | SED '#这是一条评论 2D'  1  3 
rRwW(读取和写入文件)

rRwW命令解析的文件名,直至行尾。如果找到空格,注释或分号,它们将被包含在文件名中,导致意想不到的结果:

$ seq 2 | sed'1w hello.txt; 2D”  1个 2   $ LS -log  总共4  -rw-RW-R-- 1 23年1月2日23时03 hello.txt的; 2d   $ cat'hello.txt; 2D”  1 

请注意,sed在自动忽略读/写错误 rRwW命令(如文件丢失)。在以下示例中,sed尝试读取名为“hello.txt; ?”。文件丢失,错误被忽略:

$ echo x | sed'1rhello.txt; N”  X 
e (命令执行)

e命令之后的任何字符直到行尾都将发送到shell。如果找到空格,注释或分号,它们将被包含在shell命令中,导致意想不到的结果:

$ echo a | SED '1E触摸富#酒吧'  一个  $ LS -1  富#酒吧  $回显| sed'1e touch foo; s / a / b /'  sh:1:s / a / b /:找不到 a 
s///[we](用e代替w

在替换命令中,w标志将替换结果写入文件,并且该e标志以shell命令执行归属结果。r/R/w/W/e命令一样,这些必须用换行符终止。如果找到空格,注释或分号,它们将被包含在shell命令或文件名中,从而导致意想不到的结果:

$ echo a | SED的/ A / B / w1.txt#富'  b   $ LS -1  的1.txt#FOO 

4地址:选择行


4.1地址概述

地址确定sed将执行命令的哪一行以下命令替换“你好'与'世界“只在第144行:

sed'144s / hello / world /'input.txt> output.txt 

如果没有给出地址,则在所有行上执行命令。以下命令替换“你好'与'世界'在输入文件的所有行:

sed / s / hello / world /'input.txt> output.txt 

地址可以包含正则表达式,以基于内容而不是行号匹配行。以下命令替换“你好'与'世界“只有在含有”苹果“:

sed'/ apple / s / hello / world /'input.txt> output.txt 

地址范围由两个以逗号(,分隔的地址指定地址可以是数字,正则表达式或两者的混合。以下命令替换“你好'与'世界“只有4到17行(含):

sed'4,17s / hello / world /'input.txt> output.txt 

!字符附加到地址规范的结尾(在命令字母之前)否定了匹配的感觉。也就是说,如果!字符遵循地址或地址范围,则仅选择与地址匹配的以下命令替换“你好'与'世界“只有包含字”苹果“:

sed'/ apple /!s / hello / world /'input.txt> output.txt 

以下命令替换“你好'与'世界'仅在第1行到第3行和第18行直到输入文件的最后一行(即排除行4到17):

sed'4,17!s / hello / world /'input.txt> output.txt 

4.2按数字选择行

sed脚本中的地址可以是以下任何一种形式:

number

指定行号仅与输入中的行匹配。(请注意,sed除非在所有输入文件之间连续计数-一世 要么 -s 选项被指定。)

$

该地址与最后一个输入文件的最后一行匹配,或者每个文件的最后一行 -一世 要么 -s 选项被指定。

first~step

GNU扩展每匹配步骤个开头的行线第一特别地,当存在非负n使得当前行数等于第一 +(n * 时,将选择行 因此,1~2可以选择奇数行和 0~2偶数行; 从第二个开始挑选第三行,2?3“将被使用; 从十号开始选择第五行,使用'10?5“; 和'50?0“只是一个模糊的说法50

以下命令演示了步骤地址使用情况:

$ seq 10 | SED -N '0?4P'  4  8   $ 10序列| SED -N '1?3P'  1  4  7  10 

4.3通过文本匹配选择行

GNU sed支持以下正则表达式地址。默认的正则表达式是 基本正则表达式(BRE)如果-E 要么 -r使用选项,正则表达式应为扩展正则表达式(ERE)语法。BRE vs ERE

/regexp/

这将选择与正则表达式正则表达式匹配的任何行如果regexp本身包含任何/字符,则每个都必须由反斜杠(\转义

以下命令打印行 / etc / passwd文件 以“庆典5

sed -n'/ bash $ / p'/ etc / passwd 

空的正则表达式“//'重复上一个正则表达式匹配(如果将空的正则表达式传递给s命令,则相同)。请注意,正则表达式的修饰符将在编译正则表达式时进行求值,因此与空正则表达式一起指定它们无效。

\%regexp%

%可以由任何其他单个字符替换。)


这也与正则表达式正则表达式匹配,但允许使用不同的定界符/如果正则表达式本身包含大量斜杠,这是特别有用的,因为它避免了每一个繁琐的转义/如果regexp本身包含任何分隔符字符,则每个都必须由反斜杠(\转义

以下两个命令是等效的。他们打印以'/家庭/爱丽丝/文件/“:

sed -n'/ ^ \ / home \ / alice \ / documents \ //  p'sed -n'\%^ / home / alice / documents /% p'sed -n'\; ^ / home / alice / documents /; p” 
/regexp/I \%regexp%I

I正则表达式匹配修饰符是GNU 扩展,它使得正则表达式以不区分大小写的方式匹配。

在许多其他编程语言中,小写字母i用于不区分大小写的正则表达式匹配。然而,在sed 该i用于插入命令(TODO:添加pxref)。

观察以下示例之间的差异。

在这个例子中,/b/I是地址:具有I 修饰符的正则表达式d是delete命令:

$ printf“%s \ n”abc | SED '/ B / ID'  一个 ? 

这里/b/是地址:正则表达式。 i是insert命令。 d是要插入的值。一条线与'?'然后插入匹配的行上方:

$ printf“%s \ n”abc | SED '/ B / ID'  一个 ?  b  ? 
/regexp/M \%regexp%M

M正则表达式匹配修饰符是GNU sed 扩展,它指示GNU sed多行模式下匹配正则表达式修饰符分别引起^$匹配换行符之后的空字符串(除正常行为之外),换行符之前的空字符串。有一些特殊的字符序列(\`\')始终与缓冲区的开头或结尾相匹配。另外,在多行模式下,句点字符与新行字符不匹配。


4.4范围地址

可以通过指定两个以逗号(,分隔的地址来指定地址范围地址范围匹配从第一个地址匹配的行开始,直到第二个地址匹配(包括):

$ seq 10 | SED -n '4,6p'  4  5  6 

如果第二个地址是一个正则表达式,然后检查结束比赛将开始与线以下,其匹配的第一个地址的行:一个范围将总是跨越至少两行(当然除了如果输入流结束时)。

$ seq 10 | SED -n '4 / [0-9] / P'  4  5 

如果第二个地址是一个小于(或等于)匹配所述第一地址的行,那么只有一条线匹配:

$ seq 10 | SED -n '4,1p'  4 

GNU sed还支持一些特殊的双地址格式; 所有这些都是GNU扩展:

0,/regexp/

0可以在地址规范中使用 行号,以便在第一个输入行中尝试匹配正则 表达式换句话说, 类似于,除了如果addr2与输入的第一行匹配,则 表单将认为其结束范围,而形式将匹配其范围的开始,因此使范围跨度达到第二次出现的正则表达式。 0,/regexp/sed0,/regexp/1,/regexp/0,/regexp/1,/regexp/

请注意,这是唯一0地址有意义的地方; 没有第0行和命令0 以任何其他方式给出地址将给出错误。

以下示例说明从地址1和0开始的区别:

$ seq 10 | SED -n '1,/ [0-9] / P'  1  2   $ SEQ 10 | SED -n '0,/ [0-9] / P'  1 
addr1,+N

匹配ADDR1?以下行ADDR1

$ seq 10 | SED -N '6,+ 2P'  6  7  8 

addr1可以是行号或正则表达式。

addr1,~N

匹配addr1addr1 之后的行,直到输入行号为N的倍数的下一行以下命令从第6行开始,直到下一行为4的倍数(即第8行):

$ seq 10 | SED -n '6,?4P'  6  7  8 

addr1可以是行号或正则表达式。


5正则表达式:选择文本


5.1正则表达式概述 sed

要知道如何使用sed,人们应该了解的正则表达式(正则表达式的简称)。正则表达式是从左到右匹配主题字符串的模式。大多数字符是 普通的:它们代表自己的模式,并且匹配相应的字符。正则表达式在sed两个斜杠之间指定。

以下命令打印包含单词“你好“:

sed -n'/ hello / p' 

上面的例子相当于这个grep命令:

grep'你好 

正则表达式的力量来自于在模式中包含替代和重复的能力。这些是通过使用特殊字符在模式中编码的,这些字符不代表自己,而是以某种特殊方式进行解释。

^正则表达式中的字符(插入符号)与行的开头匹配。字符.(点)匹配任何单个字符。以下sed命令匹配并打印以字母“b',其次是任何一个字符,其次是字母'?“:

$ printf“%s \ n”abode bad bed bit bid byte body | sed -n'/ ^ bd / p'  招标 机构 

以下部分说明正则表达式中特殊字符的含义和用法。


5.2基本(BRE)和扩展(ERE)正则表达式

基本和扩展正则表达式是指定模式语法的两个变体。基本正则表达式(BRE)是sed(和类似的)中的默认值grep扩展正则表达式语法(ERE)被激活-r 要么 -E选项(和类似地,grep -E)。

GNU中 sed,基本和扩展正则表达式的唯一区别在于几个特殊字符的行为:'''+',括号,大括号('{}'),和'|”。

使用基本(BRE)语法,这些字符没有特殊的含义,除非前缀反斜杠('\“); 虽然使用扩展(ERE)语法是相反的:这些字符是特殊的,除非它们带有反斜杠('\“)。

所需模式 基本(BRE)语法 扩展(ERE)语法
文字'+'(加号)
$ echo“a + b = c”| sed -n'/ a + b / p'a  + b = c 
$ echo“a + b = c”| sed -E -n'/ a \ + b / p'a  + b = c 
一个或多个 '一个'字符后跟'b'(加号作为特殊元字符)
$ echo“aab”| sed -n'/ a \ + b /  p'aab 
$ echo“aab”| sed -E -n'/ a + b /  p'aab 

5.3基本正则表达式语法概述

以下是正则表达式语法的简要说明sed

char

一个普通字符与自己相匹配。

*

匹配上一个正则表达式的零个或多个匹配实例的序列,该正则表达式必须是普通字符,前缀为\.,分组的正则表达式(见下文)或括号表达式的特殊字符作为GNU扩展,后缀正则表达式也可以后跟*例如,a**相当于a*。 POSIX 1003.1-2001表示,*当它出现在正则表达式或子表达式的开始时,它代表自身,但是许多非GNU实现不支持这一点,便携式脚本应该\*在这些上下文中使用

.

匹配任何字符,包括换行符。

^

匹配模式空间开始处的空字符串,即,在模式空格开始之后,必须显示出来的内容。

在大多数脚本中,模式空间被初始化为每行的内容(请参阅如何sed工作)。所以,这是一个有用的简化,认为是^#include只匹配线,#包括'是线上的第一件事 - 如果以前有空格,比如匹配失败。只要模式空间的原始内容不被修改,例如使用s命令,这种简化是有效的

^仅在正则表达式或子表达式(即,之后\(或 之后\|的开始处作为特殊字符^尽管如此,便携式脚本在子表达式开始时应避免,因为POSIX允许^在该上下文中将其视为普通字符。

$

它是一样的^,而是指模式空间的结尾。 $也只能在正则表达式或子表达式(即,之前\) 或之前\|的结尾处作为特殊字符,并且在子表达式结尾处的使用不可移植。

[list] [^list]

匹配列表中的任何单个字符:例如, [aeiou]匹配所有元音。列表可以包括与(包括)char1 和char2之间的任何字符匹配的序列请参阅字符类和括号表达式char1-char2

\+

因为*,但匹配一个或多个。这是一个GNU扩展。

\?

作为*,但只匹配零或一。这是一个GNU扩展。

\{i\}

As *,但是恰好匹配i序列(是一个十进制整数;为了便携性,保持在0到255之间)。

\{i,j\}

匹配ij,包括序列。

\{i,\}

匹配大于或等于i序列。

\(regexp\)

将内部正则表达式组合为一个整体,这用于:

  • 应用postfix操作符,如\(abcd\)*:这将搜索零个或多个整个序列'A B C D',同时abcd*会搜索'ABC“其次是零次或多次出现”?”。请注意,POSIX 1003.1-2001 \(abcd\)*需要支持,但许多非GNU 实现不支持它,因此它不是普遍可移植的。
  • 使用回参考(见下文)。
regexp1\|regexp2

匹配regexp1regexp2使用括号来使用复杂的替代正则表达式。匹配过程从左到右依次尝试每个替代,并且使用成功的第一个。这是一个GNU扩展。

regexp1regexp2

匹配regexp1regexp2的连接级联地结合不同于更紧密\|^和 $,但较不紧密比其他正则表达式运算符。

\digit

匹配的数字\(…\)正则表达式括号子表达式。这被称为反参考子表达式通过计数\(从左到右的出现来隐含地编号

\n

匹配换行符。

\char

匹配,其中,焦炭是一个$, *.[\,或^请注意,您可以移植地假定要解释的只有C样的反斜杠序列是\n\\特别 \t是不便携,并且匹配'?“在大多数实现的sed,而不是制表符字符。

请注意,正则表达式匹配器是贪心的,即从左到右尝试匹配,如果从同一个字符开始可以进行两次或多次匹配,则选择最长的匹配项。

例子:

ABCDEF

火柴 'ABCDEF”。

A * B

匹配零个或多个'一个之后是一个单一的“b”。例如, 'b' 要么 'AAAAAB”。

一\ 2 B

火柴 'b' 要么 'AB”。

一个\ + B \ +

匹配一个或多个'一个其次是一个或多个'b的:'AB“是最短的匹配,但其他例子是”AAAAB' 要么 'abbbbb' 要么 'aaaaaabbbbbbb”。

*。 。\ +

这两个都匹配字符串中的所有字符; 但是,第一个匹配每个字符串(包括空字符串),而第二个匹配只包含至少一个字符的字符串。

^为主。*(。*)

这匹配一个以'主要',其次是开口和右括号。?''''和'“不必相邻。

^#

这匹配一个以'”。

\\ $

这将匹配以单个反斜杠结尾的字符串。正则表达式包含两个用于转义的反斜杠。

\ $

而是匹配一个由一个美元符号组成的字符串,因为它被转义。

[A-ZA-Z0-9]

在C语言环境中,它匹配任何ASCII字母或数字。

[^ tab] \ +

(这里tab表示单个制表符。)这匹配一个或多个字符的字符串,其中没有一个是空格或制表符。通常这意味着一个字。

^ \(。* \)\ n \ $ 1

这将匹配由由换行符分隔的两个相等子串组成的字符串。

\ {9 \}一个$

这匹配九个字符,后跟一个'一个“在一行的结尾。

^ \ {15 \}甲

这匹配一个包含16个字符的字符串的开头,最后一个是'一个”。


5.4扩展正则表达式语法概述

基本和扩展正则表达式的唯一区别在于几个字符的行为:'''+',括号,大括号('{}'),和'|”。虽然基本的正则表达式要求将它们转义为特殊字符,但如果您希望它们与文字字符匹配,则使用扩展正则表达式时,必须将其转义|因为'\ |'是一个GNU扩展 - 标准的基本正则表达式不提供其功能。

例子:

abc?

成为'ABC \?'使用扩展正则表达式时。它匹配文字字符串'ABC?”。

c\+

成为'C +'使用扩展正则表达式时。它匹配一个或多个'C的。

a\{3,\}

成为'一个{3,}'使用扩展正则表达式时。它匹配三个或更多的'一个的。

\(abc\)\{2,3\}

成为'(ABC){2,3}'使用扩展正则表达式时。它匹配“ABCABC' 要么 'ABCABCABCABC ...”。

\(abc*\)\1

成为'(ABC *)\ 1'使用扩展正则表达式时。使用扩展正则表达式时,还需要转义引用引用。

a\|b

成为'A | B'使用扩展正则表达式时。它匹配'一个' 要么 'b”。


5.5字符类和括号表达式

括号表达式是由包围字符的列表'['和']”。它匹配该列表中的任何单个字符; 如果列表的第一个字符是插入符号'^',那么它匹配任何不在列表中的字符例如,以下命令将替换“灰色' 要么 '灰色'与'蓝色“:

sed的/ gr [ae] y / blue /' 

括号表达式可用于 基本扩展 正则表达式(即,带或不带-E/-r 选项)。

在括号表达式中,范围表达式由用连字符分隔的两个字符组成。它匹配在两个字符之间排序的任何单个字符(包括)。在默认的C语言环境中,排序顺序是本地字符顺序; 例如, '[广告]'相当于'[A B C D]”。

最后,某些命名类的字符是在括号表达式中预定义的,如下所示。

这些命名类必须括号内使用正确使用:

$ echo 1 | sed's / [[:digit:]] / X /'  X 

不正确的使用被较新的sed版本拒绝旧版本接受它,但将其视为单括号表达式(相当于“[DGIT:]',也就是只有字符d / g / i / t /:)

#当前的GNU sed版本 - 不正确的使用被拒绝 $ echo 1 | sed的/ [:digit:] / X /'  sed:字符类的语法是[[:space:]],而不是[:space:]   #旧的GNU sed版本 $ echo 1 | sed / s / [:digit:] / X /'  1 
[:alnum:]

字母数字字符: '[:α:]'和'[:数字:]“; 在里面 'C'区域设置和ASCII字符编码,这与'[0-9A-ZA-Z]”。

[:α:]

字母字符:'[:降低:]'和'[:上:]“; 在里面 'C'区域设置和ASCII字符编码,这与'[A-ZA-Z]”。

[:空白:]

空白字符:空格和制表符。

[:CNTRL:]

控制字符 在ASCII中,这些字符具有八进制代码000到037和177(DEL)。在其他字符集中,这些是相同的字符,如果有的话。

[:数字:]

数字:0 1 2 3 4 5 6 7 8 9

[:图形:]

图形字符:'[:alnum:]'和'[:PUNCT:]”。

[:降低:]

小写字母; 在里面 'C'区域设置和ASCII字符编码,这是 a b c d e f g h i j k l m n o p q r s t u v w x y z

[:打印:]

可打印字符:'[:alnum:]'''[:PUNCT:]'和空间。

[:PUNCT:]

标点符号 在里面 'C'区域设置和ASCII字符编码,这是 ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~

[:空间:]

空间人物:在'C'locale,这是标签,换行符,垂直标签,表单feed,回车和空格。

[:上:]

大写字母:在'C'区域设置和ASCII字符编码,这是 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

[:xdigit:]

十六进制数字: 0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f

请注意,这些类名称中的括号是符号名称的一部分,除了括号表达式的括号之外,还必须包含它们。

大多数元字符在括号表达式中丧失其特殊含义:

]

如果不是第一个列表项,则结束括号表达式。所以,如果你想让']'字符是一个列表项,你必须把它放在第一位。

 - 

表示范围,如果它不是列表中的第一个或最后一个或范围的终点。

^

表示不在列表中的字符。如果你想让'^'字符列表项,放在任何地方,但首先。

TODO:并入本段(从BRE部分逐字复制)。

字符$*.[,和\ 通常不中的特殊列表例如,[\*] 匹配“\' 要么 '*'因为\这里不是特别的。然而,字符串等[.ch.][=a=]和 [:space:]是内特殊列表和表示对照的符号,等价类,和字符类,分别和 [因此特别内列表时,它后面是 .=,或:此外,在不 POSIXLY_CORRECT模式,特殊的逃逸喜欢\n和 \t内确认名单看到逃生

[

表示开放的整理符号。

]

代表紧密整理符号。

[=

表示开放等价类。

=]

代表密切的等价类。

[:

表示打开的字符类符号,后面应该有一个有效的字符类名称。

:]

代表关闭字符类符号。


5.6正则表达式扩展

以下序列在正则表达式中具有特殊含义(在地址s命令中使用)。

这些可以用于 基本扩展 正则表达式(即,使用或不使用-E/-r 选项)。

\w

匹配任何“单词”字符。“字”字符是任何字母或数字或下划线字符。

$ echo“abc% -  = def”。| sed / / w / X /  g'XXX% -  = XXX。 
\W

匹配任何“非字”字符。

$ echo“abc% -  = def”。| sed的/ \ W / X /  g'abcXXXXXdefX 
\b

匹配单词边界; 如果左边的字符是“字”字符,并且右边的字符是“非字”字符,则反之亦然。

$ echo“abc% -  = def”。| sed的/ \ b / X /  g'XabcX% -  = XdefX。 
\B

匹配到处都是字边界; 如果左边的字符和右边的字符既是“字”字符也可以是“非字”两个字符,那就是匹配。

$ echo“abc% -  = def”。| sed的/ \ w / X /  g'aXbXc X%XX = X dXeXf.X 
\s

匹配空格字符(空格和制表符)。嵌入模式/保持空格的换行符也将匹配:

$ echo“abc% -  = def”。| sed / s / X /  g'abcX% -  = Xdef。 
\S

匹配非空格字符。

$ echo“abc% -  = def”。| sed的/ \ w / X /  g'XXX XXX XXXX 
\<

匹配一个单词的开头。

$ echo“abc% -  = def”。| sed's / \ <!-- X /  g'Xabc% -  = Xdef。 
\>

匹配一个单词的结尾。

$ echo“abc% -  = def”。| sed's / \> / X /  g'abcX% -  = defX。 
\`

只匹配模式空间的开始。这与^多行模式不同。

比较以下两个例子:

$ printf“a \ nb \ nc \ n”| sed'N; N; s / ^ / X /  gm'Xa  Xb  Xc   $ printf“a \ nb \ nc \ n” sed'N; N; s / \`/ X /  gm'Xa  b  c 
\'

仅匹配模式空间的结尾。这与$多行模式不同。


5.7反向引用和子表达式

反向引用是指匹配的正则表达式的前一部分的正则表达式命令。反向引用使用反斜杠和单个数字(例如“\ 1“)。它们引用的正则表达式的一部分称为 子表达式,并用括号指定。

反向引用和子表达式用于两种情况:正则表达式搜索模式和命令替换部分s(请参阅正则表达式地址“s”命令)。

在正则表达式模式中,使用反向引用来匹配与先前匹配的子表达式相同的内容。在下面的例子中,子表达式是'' - 任何单个字符(被括号括起来使其成为子表达式)。反参考“\ 1'要求与子表达式匹配相同的内容(相同字符)。

下面的命令匹配以任何字符开始的单词,后跟字母“?',其次是与第一个相同的字符。

$ sed -E -n'/^(.)o\1$/p'/ usr / share / dict / words  bob  mom  non  pop  sos  tot  wow 

多个子表达式将从左到右自动编号。此命令搜索6个字母的回文(前三个字母为3个子表达式,后跟3个反向引用相反顺序):

$ sed -E -n'/^(.)(.)(.)\3\2\1$/p'/ usr / share / dict / words  redder 

s命令中,可以在替换部分中使用反向引用来引用regexp部分中的表达式

以下示例使用正则表达式中的两个子表达式来匹配两个空格分隔的单词。替换部件中的反向引用以不同的顺序打印单词:

$ echo“James Bond”| sed -E /(.*)(。*)/名称为\ 2,\ 1 \ 2. /'  名称为Bond,James Bond。 

当与交替使用时,如果组不参与匹配,则反向引用使整个匹配失败。例如, '一个(。)| b \ 1“不匹配”BA”。当给出多个正则表达式时-e 或从文件('-f 文件'),反向引用是每个表达式的本地。


5.8转义序列 - 指定特殊字符

直到本章,我们才遇到过“\ ^“,它sed不会把回旋解释为一个特殊的角色,而是从字面上来说。例如, '\ *'匹配单个星号,而不是零个或多个反斜杠。

本章介绍了另外一种逃逸6,即应用于字符或字符序列的转义,这些字符或序列通常是字面上的,并sed以特殊字符替代。这提供了以可见方式对图案中的不可打印字符进行编码的方法。sed脚本中的非打印字符的外观没有限制,但是当在shell中编写脚本或通过文本编辑时,通常使用以下转义序列之一比其代表的二进制字符更容易:

这些转义的列表是:

\a

产生或匹配BEL字符,即“警报”(ASCII 7)。

\f

生成或匹配换页(ASCII 12)。

\n

生成或匹配换行符(ASCII 10)。

\r

生成或匹配回车符(ASCII 13)。

\t

生成或匹配水平选项卡(ASCII 9)。

\v

产生或匹配所谓的“垂直标签”(ASCII 11)。

\cx

产生或匹配,其中x是任何字符。CONTROL-x\ c x'如下:如果x是小写字母,则将其转换为大写字母。然后字符(十六进制40)的第6位被反转。因此'\ CZ'变成十六进制1A,但'\C{'变成十六进制3B,而'\C;'变成十六进制7B。

\dxxx

生成或匹配十进制ASCII值为xxx的字符

\oxxx

生成或匹配八进制ASCII值为xxx的字符

\xxx

生成或匹配十六进制ASCII值为xx的字符

\ b由于与现有的“字边界”的冲突,“(退格)被忽略。


5.9语言环境注意事项

TODO:修复以下段落(从“括号表达式”部分逐字复制)。

TODO:提到语言环境支持在很大程度上取决于OS / libc,而不是sed。

当前区域设置会影响与sed正则表达式匹配的字符

在其他地区,排序顺序没有指定,而'[广告]“可能相当于”[A B C D]' 或者 '[aBbCcDd]',或者它可能无法匹配任何字符,或者它匹配的字符集可能甚至是不规则的。要获得对括号表达式的传统解释,可以使用“C'locale通过将 LC_ALL环境变量设置为值'C”。

#TODO:是否有任何真实世界的系统/区域设置'A'  #被' - '替换? $ echo A | SED的/ [AZ] / - /'  

他们的解释取决于LC_CTYPE地区; 例如, '[[:alnum:]]是指当前语言环境中的数字和字母的字符类。

TODO:整理的示例

#TODO:这适用于glibc系统,而不是在musl-libc / freebsd / macosx上。 $ printf'clich?©\ n'| LC_ALL = fr_FR.utf8 sed's / [[= e =]] / X /  g'clichX 

6高级sed:循环和缓冲区


下一个:保持和模式缓冲区,向上:高级sed   [ 目录 ] [ 索引 ]

6.1 sed工作原理

sed维护两个数据缓冲区:活动模式空间和辅助保持空间。两者最初都是空的。

sed通过在每行输入上执行以下循环来操作:首先,sed从输入流中读取一行,删除任何尾随的换行符,并将其放在模式空间中。然后执行命令; 每个命令可以具有与之相关联的地址:地址是一种条件代码,只有在执行命令之前验证条件时才执行命令。

当脚本结束到达时,除非 -n选项正在使用中,模式空间的内容将打印到输出流中,如果删除尾随的换行符,则返回。7然后下一个循环开始下一个输入行。

除非特殊命令(如“?'),在两个周期之间删除模式空间。另一方面,保持空间将数据保留在周期之间(参见命令'H'''H'''X'''G'''G'在两个缓冲区之间移动数据)。


6.2保持和模式缓冲区

去做



6.3多线技术 - 使用D,G,H,N,P来处理多条线

多行可以如一个缓冲器使用被处理 DGHNP它们类似于其小写同行(dg, hnp),所不同的是这些命令追加或同时尊重嵌入换行符减去数据-允许从图案添加和删除行和保持的空间。

它们的操作如下:

D

从模式空间中删除行直到第一个换行符,然后重新启动循环。

G

行从保留空间追加到模式空间,并在其前加上换行符。

H

线从模式空间追加到保持空间,并在其前面加上换行符。

N

行从输入文件追加到模式空间。

P

从图案空间打印到第一个换行符。

以下示例说明了操作N和 D命令:

$ seq 6 | sed -n'N; l; D'  1 \ n2 $  2 \ n3 $  3 \ n4 $  4 \ n5 $  5 \ n6 $ 
  1. sed 首先将第一行读入模式空间(即'1“)。
  2. 在每个循环开始时,N 命令将附加一个换行符和下一行到模式空间(即'1'''\ n'''2'在第一个周期)。
  3. l命令明确地打印模式空间的内容。
  4. D然后,命令将图形空间的内容移除到第一个换行符(离开'2“在第一个周期结束时)。
  5. 在下一个循环中,N命令将一个换行符和下一个输入行添加到模式空间(例如“2'''\ n'''3“)。

处理文本块(例如段落(而不是逐行))的常用技术是使用以下构造:

sed'/./{H;$!d}; X ; S / REGEXP / REPLACEMENT /” 
  1. 第一个表达式/./{H;$!d}在所有非空行上运行,并将当前行(在模式空间中)添加到保留空间。在除最后一行之外的所有行上,模式空间被删除,周期重新启动。
  2. 的其他表达式xs仅在空行(即,段分隔符)来执行。x命令将累积的行从保留空间中取回到模式空间。s///然后,该 命令对段落中的所有文本(包括嵌入的换行符)进行操作。

以下示例演示了此技术:

$ cat input.txt  aaa aa aaa  aaaa aaaa aa  aaaa aaa aaa   bbbb bbb bbb  bb bb bbb bb  bbbbbbbb bbb   ccc ccc cccc  cccc ccccc c  cc cc cc cc   $ sed'/./{H;$!d}; X ; s / ^ / \ nSTART  - > /; s / $ / \ n < -  END /'input.txt   START  - >  aaa aa aaa  aaaa aaaa aa  aaaa aaa aaa  < -  END   START  - >  bbbb bbb bbb  bb bb bbb bb  bbbbbbbb bbb  < -  END   START - >  ccc ccc cccc  cccc ccccc c  cc cc cc cc  < -  END 

有关更多注释的示例,请参阅跨多行的文本搜索 和行长度调整


6.4分支和流量控制

分支命令bt并且T能够改变sed程序的流程

默认情况下,sed将输入行读入模式缓冲区,然后继续按顺序处理所有命令。没有地址的命令影响所有行。具有地址的命令仅影响匹配行。请参阅执行循环地址概述

sed不支持典型的if/then结构。相反,一些命令可以用作条件或更改默认流控制:

d

删除(清除)当前的图案空间,并重新启动程序循环,而不处理其余的命令,而不打印图案空间。

D

删除图形空间的内容直到第一个换行符,并重新启动程序循环,而不处理其余的命令,而不打印图案空间。

[addr]X [addr]{ X ; X ; X } /regexp/X /regexp/{ X ; X ; X }

地址和正则表达式可以用作if/then 条件:如果[addr]与当前模式空间匹配,请执行命令。例如:该命令/^#/d表示: 如果当前模式与正则表达式^#(以哈希开始的行)匹配执行d命令:删除该行而不打印该行,并立即重新启动程序循环。

b

无条件分支(即:总是跳到标签,跳过或重复其他命令,而不重新启动新的循环)。结合地址,可以在匹配的行上有条件地执行分支。

t

分支条件(即:跳转到一个标签)只有一个 s///命令已成功自上次输入行读取或其他条件分支被采用。

T

类似但与t命令相反:只有在从最后一条输入行被读取以来没有成功的替换时才会分支

以下两个sed程序是等效的。第一个(设计的)示例使用b命令来跳过s/// 包含'1”。第二个例子使用一个带有否定的地址('')仅在所需的行上执行替换。y///命令仍然执行在所有行:

$ printf'%s \ n'a1 a2 a3 | sed -E'/ 1 / bx; s / a / z /; :X ; y /  123/456 /'  a4 z5  z6   $ printf'%s \ n'a1 a2 a3 | sed -E'/ 1 /!s / a / z /; y /  123/456 /'  a4 z5  z6 
6.4.1分支和周期

bt并且T命令可被随后的标签(通常是一个字母)。标签用冒号定义,后跟一个或多个字母(例如“:X“)。如果省略标签,则分支命令重新启动循环。注意分支到标签和重新启动循环之间的区别:重新启动循环时,sed首先打印模式空间的当前内容,然后将下一个输入行读入模式空间; 跳到标签(即使在程序开头)也不会打印图案空间,也不会读取下一个输入行。

以下程序是无操作的。b命令(在程序中仅命令)不具有一个标签,并由此简单地重新开始该循环。在每个循环中,打印图案空间,并读取下一个输入行:

$ seq 3 | sed b  1  2  3 

以下示例是无限循环 - 它不会终止,也不会打印任何内容。b命令跳转到“X'标签,一个新的循环从未开始:

$ seq 3 | sed':x; bx'   #上述命令需要gnu sed(支持附加 #命令后面的标签,不带换行符)。一个便携式的等价物: #sed -e':x'-e bx 

分支通常用nN命令来补充:两个命令都将下一个输入行读入模式空间,而无需等待重新启动循环。在读取下一个输入行之前,n 打印当前图案空间,然后将其排空,同时N将一个换行符和下一个输入行附加到模式空间。

考虑以下两个例子:

$ seq 3 | sed':x; n; BX”  1  2  3   $ SEQ 3 | sed':x; N; BX”  1  2  3 
  • 尽管没有开始新的循环,这两个例子都不会进行循环。
  • 在第一个示例中,n命令首先打印模式空间的内容,清空模式空间,然后读取下一个输入行。
  • 在第二个示例中,N命令将下一个输入行附加到模式空间(带换行符)。线路在图形空间中累积,直到没有更多输入行读取,则N命令终止sed程序。当程序终止时,执行周期结束动作,并打印整个模式空间。
  • 第二个例子需要GNU sed,因为它使用非POSIX标准的行为N请参阅报告错误中的N “最后一行的命令”一节
  • 要进一步检查两个示例之间的区别,请尝试以下命令:
    printf'%s \ n'aa bb cc dd | sed':x; n; =; bx'printf'  %s \ n'aa bb cc dd | sed':x; N; =; bx'printf'  %s \ n'aa bb cc dd | sed':x; n; s / \ n / *** /; bx'printf'  %s \ n'aa bb cc dd | sed':x; N; s / \ n / *** /; BX” 
6.4.2分支示例:连线

作为使用分支的现实世界示例,请考虑通常用于对电子邮件进行编码引用可打印文件的情况 在这些文件中,长行被分割并标有一个软线路断点, 由一个单一的“='字符在行尾:

$ cat jaques.txt  所有的wor =  ld都是stag =  e, 而所有=  男人和 男人只是男人=  玩家: 他们有t =  继承人退出=  和他们的e =  ntrances;  一个人=  在他的tim =  e扮演man =  y部分。 

以下程序使用地址匹配'/ = $ /'作为条件:如果当前模式空间以'=',它读取下一个输入行使用N,替换所有'='字符,其后面是换行符,并且无条件地将branch(b)分配到程序的开头,而不重新启动新的循环。如果图案空间不以“=',执行默认动作:打印模式空间并启动新的循环:

$ sed':x; / = $ / {N; s / = \ n // g; bx}'jaques.txt  所有的世界都是一个舞台, 所有的男人和女人只是一个玩家: 他们有出口和入口;  一个人在他的时间玩很多部分。 

这是一个替代程序,略有不同的方法:除了最后一行之外的所有行,N将行添加到模式空间。替换命令然后删除软换行符('=“在一行的末尾,即后跟一个换行符),用空字符串替换它们。 如果替换成功(意味着模式空间包含应该连接的行),条件转移命令将t跳转到程序的开头,而不必完成或重新启动循环。如果替换失败(意味着没有换行符),则该t命令不会分支。然后,P将打印图案空间内容直到第一个换行,D 并将删除图案空间内容直到第一个新行。(如需了解更多有关NPD命令看多线技术)。

$ sed':x; $!N; s / = \ n //; tx; P; D'jaques.txt  所有的世界都是一个舞台, 所有的男人和女人只是玩家: 他们有他们的出口和入口;  一个人在他的时间玩很多部分。 

有关更多线连接示例,请参阅连接线


7一些示例脚本

这里有一些sed脚本可以指导您掌握掌握的技巧 sed


下一步:定心线,向上:示例   [ 内容 ] [ 索引 ]

7.1连线

本节使用NDP命令以处理多行,并且bt分支命令。请参阅多线技术分支和流控制

加入特定行(例如,如果第2和第3行需要连接):

$猫lines.txt  你好 HEL  LO  你好  $ sed的'2 {N; S / \ n //;}' lines.txt  你好 你好 你好 

加入反斜杠 - 继续行:

$ cat 1.txt  这个\  is \  a \  long \  line  和另一个\  line   $ sed -e':x / \\ $ / {N; s / \\\ n // g; bx}'1.txt  这是一条长行 ,另一行  #TODO:上面需要gnu sed。 #non-gnu seds需要在':'和'b'之后换行 

加入以空格开头的行(例如SMTP标头):

$ cat 2.txt  主题:Hello  World  Content-Type:multipart / alternative;  boundary = 94eb2c190cc6370f06054535da6a  日期:星期二,2017年1月3日19:41:16 +0000(GMT) 验证结果:mx.gnu.org;  dkim = pass header.i=@gnu.org;  spf = pass  Message-ID:  来自:John Doe   To:Jane Smith    $ sed -E':a; $!N; s / \ n \ s + / /; ta P; D'2.txt  主题:Hello World  Content-Type:multipart / alternative; boundary = 94eb2c190cc6370f06054535da6a  日期:星期二,2017年1月3日19:41:16 +0000(GMT) 验证结果:mx.gnu.org; dkim = pass header.i=@gnu.org; SPF =通 Message-ID:  来自:John Doe   To:Jane Smith    #一个便携式(非gnu)变体:#sed  -e:a  - e'$!N; s / \ n * / /; ta'-e'P; D' 

7.2中心线

这个脚本将文件的所有行都放在80列的宽度上。要更改该宽度,\{…\}必须更换数字,并且必须更改添加空格的数量。

请注意缓冲区命令如何用于分离正则表达式中要匹配的部分 - 这是一种常见的技术。

#!/ usr / bin / sed -f 
#在缓冲区中放置80个空格 1 {  x  s / ^ $ / /  s /^.*$/&&&&&&&&/  x  } 

#删除前导和尾随空格 y / tab/ /  s / ^ * //  s / * $ // 

#添加一个换行符和80个空格到行结束 G 

#保持前81个字符(80 +一个换行符) s / ^ \(。\ {81 \} \)。* $ / \ 1 / 

#\ 2匹配一半的空格,这些空格被移动到开头 s / ^ \(。* \)\ n \(。* \)\ 2 / \ 2 \ 1 / 

7.3增加数字

这个脚本是演示如何进行算术的几个脚本之一sed这的确是可能的,8但必须手动完成。

要增加一个数字,只需将1加到最后一位数字,将其替换为以下数字。有一个例外:当数字是九位数时,前面的数字也必须递增,直到没有九位数字。

Bruno Haible的这个解决方案非常聪明聪明,因为它使用单个缓冲区; 如果您没有此限制,则编号行中使用的算法更快。它通过用下划线替换尾随九进制,然后使用多个s命令递增最后一个数字,然后再次用0来替换下划线。

#!/ usr / bin / sed -f   / [^ 0-9] / d 
#替换所有尾随的9s by _(除数字之外的任何其他字符,可以使用 #) :d  s / 9 \(_ * \)$ / _ \ 1 /  td 

#incr只有最后一位数字。 如果我们必须添加一个数字,第一行添加最重要的#位数1。 

S / ^ \(_ * \)$ / 1 \ 1 /; tn  s / 8 \(_ * \)$ / 9 \ 1 /; tn  s / 7 \(_ * \)$ / 8 \ 1 /; tn  s / 6 \(_ * \)$ / 7 \ 1 /; tn  s / 5 \(_ * \)$ / 6 \ 1 /; tn  s / 4 \(_ * \)$ / 5 \ 1 /; tn  s / 3 \(_ * \)$ / 4 \ 1 /; tn  s / 2 \(_ * \)$ / 3 \ 1 /; tn  s / 1 \(_ * \)$ / 2 \ 1 /; tn  s / 0 \(_ * \)$ / 1 \ 1 /; TN 

:n  y / _ / 0 / 

7.4将文件重命名为小写

这是一个非常奇怪的用法sed我们转换文本,并将其转换为shell命令,然后将其提供给shell。不要担心,使用时更糟糕的是黑客sed我看到一个脚本将输出date转换为bc程序!

其主体是sed脚本,将名称从下到上(或反之亦然)重新映射,甚至检查重映射的名称是否与原始名称相同。注意脚本如何使用shell变量和正确的引用进行参数化。

#!/ bin / sh  #rename files to lower / upper case ...  ## usage: #move-to-lower *  #move-to-upper *  #或 #move-to-lower -R。 #move-to-upper -R。 

help() {  cat << eof  用法:$ 0 [-n] [-r] [-h]文件... 

- 不做任何事情,只看到会做什么 -R递归(使用find) -h这个消息 文件文件重映射到小写 

示例: $ 0 -n *(看是否一切正常,然后...) $ 0 * 
 $ 0 -R。 
eof  } 

apply_cmd ='sh'finder ='  echo“$ @”| tr“”“\ n”'  files_only = 

while: do-  case“$ 1”in  -n)apply_cmd ='cat';;  -R)finder ='find“$ @”-type f';;  -h)帮助; 出口1 ;;  *)break ;;  esac  完成 

如果[-z“$ 1”]; 然后 echo用法:$ 0 [-h] [-n] [-r] files ...  exit 1  fi 

LOWER ='abcdefghijklmnopqrstuvwxyz'UPPER  ='ABCDEFGHIJKLMNOPQRSTUVWXYZ' 

case  * basename $ 0` in * upper *)TO = $ UPPER; FROM = $ LOWER ;;  *)FROM = $ UPPER; TO = $ LOWER ;;  ESAC 
 eval $ finder | sed -n' 
#删除所有尾部斜杠 s / \ / * $ // 

#添加./如果没有路径,只有文件名 / \ //!小号/^/.\// 

#save path + filename  h 

 #remove path s /.*///// 

#仅转换文件名 y /'$ FROM'/'$ TO'/ 

#now line包含原始路径+文件,而 #个空格包含新的文件名 x 

#将转换的文件名添加到行,现在包含 #path / file-name \ nconverted-file-name  G 

#检查转换的文件名是否等于原始文件名, #如果是,请不要打印任何 /^.*\/\(.*\)\n\1/b 

#转义shell 特殊字符s / [“$`\\] / \\&/ g 

#now,将路径/ fromfile \ n转换为 #mv path / fromfile path / tofile并打印 s / ^ \(。* \ / \)\(。* \)\ n \(。* \)$ / mv “\ 1 \ 2”“\ 1 \ 3”/ p 
 '| $ apply_cmd 

7.5打印bash环境

该脚本从setBourne-shell命令的输出中剥离shell函数的定义

#!/ bin / sh的 
set | sed -n'  :x 

#如果没有发生'=()'打印并加载下一行 / =()/!{p; b; }  /()$ /!{p; b; } 

#可能启动函数部分 #保存行,以防万一这是一个var像FOO =“()”  h 

#如果下一行有一个括号,我们退出,因为 #没有任何东西在函数 n  / ^ {/ q之后 

打印旧行 x; p 

现在在新线上工作 x; bx  ' 

7.6线的反转字符

该脚本可用于反转行中字符的位置。该技术一次移动两个字符,因此它比更直观的实现更快。

注意tx在标签定义之前命令。这通常需要重置由该t命令测试的标志

想象力的读者将会找到这个脚本的用法。一个例子是扭转输出banner9

#!/ usr / bin / sed -f   /../!b 
#反转一行 开始在两个换行符之间嵌入行 s /^.*$/ \  &\  / 

#移动第一个字符在结尾。正则表达式匹配直到 #在标记之间有零个或一个字符 tx  :x  s / \(\ n。\)\(。* \)\(。\ n \)/ \ 3 \ 2 \ 1 /  tx 

#删除换行符 s / \ n // g 

7.7跨多行的文本搜索

本节使用ND命令来搜索跨越多行连续字。参见多线技术

这些例子涉及在文件中发现双重发生的词语。

在一行中寻找重复的单词是容易使用GNU grep 和类似地用GNU sed

$ cat two-cities-dup1.txt  这是最好的时代, 这是最糟糕的时代, 那是智慧的年龄, 那是愚昧的年龄,  $ grep -E'\ b(\ w +)\ s + \ 1 \ b'two-cities-dup1.txt  它是智慧的年龄,  $ grep -n -E'\ b(\ w +)\ s + \ 1 \ b'two-cities-dup1.txt  3:这是智慧的年龄,  $ sed -En'/ \ b(\ w +)\ s + \ 1 \ b / p'two-cities-dup1.txt  它是智慧的年龄,  $ sed -En' \ b(\ w +)\ s + \ 1 \ b / {=; p}'two-cities-dup1.txt  3  这是智慧的时代, 
  • 正则表达式“\ B \ W + \ S +搜索字边界('\ b'),后跟一个或多个字符('\ w +'),其次是空格('\ S +“)。请参阅regexp扩展
  • 在“(\ W +)'表达式创建一个子表达式。正则表达式模式'(PATTERN)\ S + \ 1'定义一个子表达式(在括号中),后跟一个由空白分隔的反向引用。成功的比赛意味着PATTERN连续重复两次。请参阅反向引用和子表达式
  • 词语表达式('\ b')在两端确保部分单词不匹配(例如'那时候'不是所需的匹配)。
  • 该 -E选项启用扩展正则表达式语法,减轻了在括号之前添加反斜杠的需要。请参阅ERE语法

当双字跨越两行时,上述正则表达式将不会找到它们grepsed逐行操作。

通过使用ND命令,sed可以在多行上应用正则表达式(即,多行存储在模式空间中,正则表达式在其上工作):

$ cat two-cities-dup2.txt  这是最好的时代,这是 最糟糕的时代,那就是 智慧的时代, 那是愚昧的时代,  $ sed -En'{N; / \ b(\ w +)\ s + \ 1 \ b / {=; p}; D}'两城 -  dup2.txt  3  最糟糕的时候,那是 智慧的时代, 
  • N命令将下一行添加到模式空间(从而确保它在每个循环中包含两个连续的行)。
  • 正则表达式使用'\ S +'用于与空格和换行匹配的单词分隔符。
  • 正则表达式匹配,整个图案空间打印p默认情况下不会打印行-n 选项。
  • 所述D去除所述图案空间的第一行(直到第一行),它准备好用于下一个循环。

请参阅GNU coreutils手册使用的替代解决方案 tr -suniq在 https://gnu.org/s/coreutils/manual/html_node/Squeezing-and-deleting.html


7.8线长调整

本节使用ND命令来搜索跨越多行的连续词,以及b分支命令。请参阅多线技术分支和流控制

这些(有些设计的)示例处理以下输入文件的格式和文字行:

$ cat two-cities-mix.txt  这是最好的时代,这是 最糟糕的时代,那 智慧的时代 愚蠢 的时代 

以下命令将换行为40个字符:

$ sed -E':x {N; s / \ n / / g; s /(。{40,40})/ \ 1 \ n /; / \ n /!bx; P; D}'\  two-cities-mix.txt  这是最好的时代,这是时代的曙光,是 智慧的时代,我 是愚蠢的时代, 

以下命令将用逗号分隔行:

$ sed -E':x {N; s / \ n / / g; s /,/,\ n /; / \ n /!bx; s / ^ * //; P; D“'\  two-cities-mix.txt  这是最好的时代, 这是最糟糕的时代, 那是智慧的时代, 那是愚昧的时代, 

两个示例使用类似的结构:

  • :X“是一个标签。b命令后面将使用该命令跳转到sed程序的开头,而不必开始新的循环。
  • ?'命令从输入文件中读取下一行,并将其附加到模式空间的现有内容(在其前面带有换行符)。
  • 首先 's / \ n / / g'命令用空格替换所有换行符,丢弃输入文件的行结构。
  • 第二 '小号///'命令根据所需的模式添加换行符(在第一个示例中为40个字符之后,第二个示例中为逗号后的字符)。
  • / \ n /!BX'命令在模式空间中搜索换行符('/ N /'),如果没有找到(''),分支(=跳转)到先前定义的标签'X”。这将导致sed 在此循环中读取下一行而不处理任何进一步的命令。
  • 如果在模式空间中找到换行符,P则用于打印到换行符(即新结构化行),然后D 删除直到换行符的模式空间,并启动新的循环。

7.9文件的反向行

这一个开始一系列完全无用(但有趣的)脚本,仿效各种Unix命令。这尤其是一种tac工作。

请注意,在GNU 以外的实现中,sed 此脚本可能容易溢出内部缓冲区。

#!/ usr / bin / sed -nf   #反转所有行输入,即第一行成为最后,... 
#从第二行,缓冲区(其中包含所有以前的行) #是*附加*到当前行,所以顺序将被反转 1!G 

#在最后一行我们完成了 - 打印一切 $ p 

#店面的一切对缓冲区再次 ^ h 

7.10编号

这个脚本取代““; 实际上它的输出格式与GNU cat一样。

当然这是完全没用的,有两个原因:第一,因为别人在C中做到了,其次,因为以下Bourne-shell脚本可以用于相同的目的,而且会更快:

#!/ bin / sh  sed -e“=”$ @ | sed -e  的/ ^ / /  N  s / ^ * \(...... \)\ n / \ 1 /  ' 

它用于sed打印行号,然后使用两行二行N当然,这个脚本不会像下面那样教导。

用于递增的算法使用两个缓冲区,因此该行将尽快打印,然后被丢弃。数字被分割,以便改变数字进入缓冲区,不变的数字进入另一个; 更改的数字将在一个步骤中修改(使用y命令)。然后将下一行的行号组合并存储在保留空间中,以便在下一次迭代中使用。

#!/ usr / bin / sed -nf 
#在第一行 排出 x / ^ $ / s /^.*$/ 1 / 

#在模式 G  h 之前添加正确的行号 

#格式化并打印 s / ^ / /  s / ^ * \(...... \)\ n / \ 1 / p 

#从保留空间获取行号; 加一个零 #如果我们要在下一行添加一个数字 S / \ n * $ //  / ^ 9 * $ / S / ^ / 0 / 

#单独更改/不变的数字与x  s / .9 * $ / x& 

#持续更改位数 h  s /^.* x //  y / 0123456789/1234567890 /  x 

#在模式空间中保持不变的数字 s / x。* $ // 

#组成新的数字,删除由G  G  s / \ n //  h 隐式添加的换行符 

7.11编号非空行

仿效'猫-b几乎和'' - 我们只需要选择哪些行被编号,哪些不是。

该脚本和前一个脚本通用的部分没有评论,以显示sed 正确注释脚本的 重要性

#!/ usr / bin / sed -nf 
/ ^ $ / {  p  b  } 

#与cat -n从现在相同 x  / ^ $ / s /^.*$/ 1 /  G  h  s / ^ / /  s / ^ * \(...... \)\ n / \ 1 / p  x  s / \ n。* $ //  / ^ 9 * $ / s / ^ / 0 /  s / .9 * $ / x&/  h  s /^.* x //  y / 0123456789/1234567890 /  x  s / x 。* $ //  G  s / \ n //  h 

7.12计数字符

这个脚本显示了另一种做算术的方式sed在这种情况下,我们必须添加大量数字,因此以连续的增量来实现这一点并不可行(并且可能比这个脚本更复杂)。

方法是将数字映射到字母,实现一种算盘sed一个是单位,'b几十个等等,我们只需将当前行的字符数加上单位,然后将进位数传播到数十,数百等。

像往常一样,运行总计保持在保持空间。

在最后一行,我们将算盘转换为十进制。为了多种多样,这是一个循环而不是约80个s命令10:首先我们转换单位,删除'一个来自数字; 然后我们旋转字母,使几十变成“一个等等,直到不再有信件。

#!/ usr / bin / sed -nf 
#添加n + 1 a来保存空格(+1为换行符) s /./ a / g  H  x  s / \ n / a / 

#做进位。经t和b的是没有必要的, #但他们加快东西 TA  :一个; S / AAAAAAAAAA / b / g的; TB; b完成 :b; S / bbbbbbbbbb / C / G; TC; b完成 :c S / CCCCCCCCCC / D / G; TD; b完成 :d S / DDDDDDDDDD / E / G; TE; b完成 :e S / eeeeeeeeee / F / G; TF; b完成 :f S / ffffffffff /克/克; TG; b完成 :g; S / GGGGGGGGGG /小时/克; 位; b完成 :h S / hhhhhhhhhh //克 

:完成 $!{  h  b  } 
 #在最后一行,转换回十进制 
:loop  / a /!s / [bh] * /&0 /  s / aaaaaaaaa / 9 /  s / aaaaaaaa / 8 /  s / aaaaaaa / 7 /  s / aaaaaa / 6 /  s / aaaaa / 5 /  s / aaaa / 4 /  s / aaa / 3 /  s / aa / 2 /  s / a / 1 / 

:next  y / bcdefgh / abcdefg /  / [ah] / b loop  p 

7.13计数单词

这个脚本与前一个脚本几乎相同,一旦这行上的每个单词被转换成一个单一的“一个'(在前面的脚本中,每封信都改为“一个“)。

有趣的是,真正的wc程序已经为“wc -c',所以他们在计数单词而不是字符时慢得多。相反,这个脚本的瓶颈是算术运算,因此字数计数更快(必须管理较小的数字)。

再次,公共部分没有评论,以显示评论sed脚本的重要性

#!/ usr / bin / sed -nf 
#将单词转换为 s / [ tab] [ tab] * / / g  s / ^ / /  s / [^] [^] * / a / g  s / // g 

#追加它们以容纳空格 H  x  s / \ n // 

#从这里,它与wc -c相同。 / AAAAAAAAAA /!BX; s / aaaaaaaaaa / b / g  / bbbbbbbbbb /!BX; s / bbbbbbbbbb / c / g  / cccccccccc /!BX; s / cccccccccc / d / g  / dddddddddd /!BX; s / dddddddddd / e / g  / eeeeeeeeee /!BX; s / eeeeeeeeee / f / g  / ffffffffff / BX; s / ffffffffff / g / g  / ggggggggg / BX; s / ggggggggg / h / g  s / hhhhhhhhhhh // g  :x  $!{ H; b; }  :y  / a /!s / [bh] * /&0 /  s / aaaaaaaaa / 9 /  s / aaaaaaaa / 8 /  s / aaaaaaa / 7 /  s / aaaaaa / 6 /  s / aaaaa / 5 /  s / aaaa / 4 /  s / aaa / 3 /  s / aa / 2 /  s / a / 1 /  y / bcdefgh / abcdefg /  / [ah] / by  p 

7.14计数线

现在没有什么奇怪的事情,因为sed给我们'wc -l'功能免费!看:

#!/ usr / bin / sed -nf  $ = 



7.15打印第一行

这个脚本可能是最简单的有用sed脚本。显示前10行输入; 显示的行数正好在q命令之前

#!/ usr / bin / sed -f  10q 

7.16打印最后一行

打印最后的n行而不是第一行更复杂,但确实可能。 n在第二行编码,在爆炸字符之前。

该脚本类似于tac脚本,它将最终输出保留在保留空间中,并将其打印到最后:

#!/ usr / bin / sed -nf 
1!{; H; G; }  1,10!s / [^ \ n] * \ n //  $ p  h 

主要是脚本保持10行的窗口,并通过添加一行并删除最旧的(第二行的替换命令像D命令一样工作但不重新启动循环)来滑动它

“滑动窗口”技术是编写高效和复杂sed脚本的非常强大的方式,因为像P手动执行的命令 需要大量的工作。

为了介绍这一技术,在本章的其余部分中得到充分的阐述NP 并且基于这一点D命令,这里是一个tail 使用简单的“滑动窗口” 的实现

这看起来很复杂,但实际上工作与最后一个脚本相同:在我们踢了适当数量的行后,我们停止使用保持空间来保持跨行状态,而是使用ND滑动模式空间一行:

#!/ usr / bin / sed -f 
1h  2,10 {; H; G; }  $ q  1,9d  N  D 

注意在前十行输入之后,第一行,第二行和第四行如何处于非活动状态。之后,所有的脚本都是:退出最后一行输入,将下一个输入行附加到模式空间,并删除第一行。


7.17使重复行独特

这是在本领域使用的一个例子NP 和D命令,可能是最难以掌握。

#!/ usr / bin / sed -f  h 

:b  #在最后一行打印并退出 $ b  N  /^\(.*\)\n\1$/ {  #两行相同。撤消#n  命令的效果 g  bb  } 

#如果N命令添加了最后一行,请打印并退出 $ b 

线条不一样; 打印第一个,然后回去 #在第二个工作。 P  D 

可以看到,我们使用P维护一个2行窗口D这种技术常用于高级sed脚本。


7.18打印输入的重复行

此脚本仅打印重复的行,如“uniq -d”。

#!/ usr / bin / sed -nf 
$ b  N  /^\(.*\)\n\1$/ {  #打印第一个重复行 s /.* \ n //  p 

 #循环直到我们得到一个不同的行 :b  $ b  N  /^\(.*\)\n\1$/ {  s /.* \ n //  bb  }  } 

#最后一行不能跟着重复的 $ b 

#找到不同的。将它单独放在模式空间 #中,并返回到顶部,狩猎其重复的 D 

7.19删除所有重复的行

此脚本仅打印独特的行,如“uniq -u”。

#!/ usr / bin / sed -f 
#搜索一个重复的行---直到那个,打印你找到的。 $ b  N  /^\(.*\)\n\1$/!{  P  D  } 

:c  #在模式空间中有两条相等的行。 文件#端,我们只需退出 $ d 

#否则,我们继续读取行,N直到我们 找到不同的一个/  /。* \ n //  N  /^\(.*\)\n\1$/ {  bc  } 

#删除重复行的最后一个实例,然后返回到顶部 D 

7.20挤压空白线

作为最后一个例子,这里有三个脚本,其复杂性和速度越来越高,实现与““那就是挤压空白线。

第一个在开始和结尾留下一个空白行,如果有一些已经。

#!/ usr / bin / sed -f 
#在空行,加入下一个 #注意在regexp中有一个明星 :x  / ^ \ n * $ / {  N  bx  } 

#现在,挤都'\ n',这也可以通过做: #s / ^ \(\ n \)* / \ 1 /  S / \ n * / \  / 

这一个有点复杂,并在开头删除所有空行。如果一个人在那里,它将在最后留下一条空白行。

#!/ usr / bin / sed -f 
#删除所有前导空行 1,/ ^。/ {  /./!d  } 

#在我们删除它,下面所有的空行 #空行,但一个 :X  !/./ {  ?  S / ^ \ n $ //  TX  } 

这将删除前导和尾随空白行。它也是最快的。需要注意的是回路完全做到n和 b,而不依赖于sed在一行结束时自动重新启动脚本。

#!/ usr / bin / sed -nf 
 #delete all(leading)blanks /./!d 

#到这里:所以有一个非空 :x  #打印它 p  #得到下一个 n  #有chars?再次打印,等...  /./bx 

#不,没有字符:有一个空行 :z  #get next,如果最后一行我们完成这里,所以没有尾随 #空行写 n  #也是空的?然后忽略它,并获得下一个...这将 #删除所有空行 /./!bz 

#所有空行都被删除/忽略,但我们有一个非空。因为 #我们想做的是挤压,人为地插入一个空白行 \ 
 BX 

GNU sed的限制和不受限制

对于那些想要编写可移植sed脚本的人,请注意,已知某些实现将线路长度(对于模式和保持空间)限制为不超过4000字节。POSIX标准规定,符合sed 实现应支持至少8192米字节行的长度。 GNU sed在线长度上没有内置限制; 只要它可以malloc()更多(虚拟)内存,只要你喜欢,你可以喂养或构建线条。

然而,递归用于处理子模式和无限期重复。这意味着可用的堆栈空间可能会限制某些模式可以处理的缓冲区的大小。


9其他资源学习关于 sed

有关GNU的 最新信息,sed请访问https://www.gnu.org/software/sed/

sed-devel@gnu.org发送一般问题和建议请访问https://lists.gnu.org/archive/html/sed-devel/过去讨论的邮件列表存档 

以下资源提供有关sed (GNU sed和其他变体)的信息。注意这些不由GNU sed开发人员维护 

  • sed $HOMEhttp : //sed.sf.net
  • sed常见问题:http : //sed.sf.net/sedfaq.html
  • seder's grabbag:http ://sed.sf.net/grabbag
  • sed-users斯文Guckes维护邮件列表: http://groups.yahoo.com/group/sed-users/ (注意,这是不是GNU sed邮件列表)。


10报告错误

bug-sed@gnu.org发送错误报告另外,请输入“sed -version“在你的报告的正文,如果可能的话。

请不要发送这样的错误报告:

同时构建frobme-1.3.4 $ configure 错误→sed:文件sedscr第1行:未知选项为's' 

如果GNU sed没有配置您喜欢的软件包,请花几分钟时间来确定具体问题,并进行独立测试。与其他程序(如C编译器)不同,使这样的测试用例sed非常简单。

一个独立的测试用例包括执行测试所需的所有数据,特定的调用sed会导致该问题。独立测试用例越小越好。测试用例不应该包含远离sed“尝试配置frobme-1.3.4”的内容。是的,这在原则上是足够的信息来寻找错误,但这不是一个非常实际的前景。

以下是几个常见的错误,不是错误。


N 命令在最后一行

大多数版本的sed退出,而不是N在文件的最后一行发出命令时打印任何东西。 GNU sed在退出前打印模式空间,除非-n指定命令开关。这个选择是设计的。

默认行为(gnu扩展名,非POSIX符合):

$ seq 3 | sed N  1  2  3 

强制符合POSIX的行为:

$ seq 3 | sed --posix N  1  2 

例如,行为

sed N foo吧 

将取决于foo是否具有偶数或奇数行11或者,在编写脚本以阅读模式匹配后的下几行时,传统的实现sed将迫使您编写类似的东西

/ foo / {$!N; !$ N; !$ N; !$ N; !$ N; !$ N; !$ N; !$ N; $!N} 

而不是只是

/ foo / {N; N; N; N; N; N; N; N; N; } 

在任何情况下,最简单的解决方法是$d;N在依赖于传统行为的脚本中使用,或将POSIXLY_CORRECT变量设置为非空值。

正则表达式语法冲突(反斜杠问题)

sed使用POSIX基本正则表达式语法。根据标准,这种语法中的一些转义序列的含义是未定义的; 在显着的情况sed\|, \+\?\`\'\<, \>\b\B\w,和\W

使用POSIX基本正则表达式的所有GNU程序中将这些转义序列解释为特殊字符。所以,匹配一个或多个出现的'sedx\+X”。 abc\|def匹配“ABC' 要么 '高清”。

运行为其他人编写的脚本时,此语法可能会导致问题 sed一些sed程序已经被写入,假设\|\+匹配文字字符 |+这些脚本必须通过他们是否与现代实现使用去除伪反斜杠进行修改sed,如 GNU sed

另一方面,一些脚本使用s | abc \ | def || g来删除任何一个 abcdef虽然这样工作,直到 sed4.0.x,较新的版本解释为删除字符串abc|def这根据POSIX再次是未定义的行为 ,而且这种解释可以说更具有鲁棒性:比较老 sed的,例如,要求正则表达式匹配器被解析 \//常见的逃避斜杠的情况,这又是未定义的行为; 新的行为避免了这一点,这是很好的,因为正则表达式匹配器只是在我们的控制之下。


此外,该版本的sed支持几个转义字符(其中一些是多字符)插入非打印字符的脚本(\a\c\d\o\r, \t\v\x)。这些可能会导致与其他人编写的脚本类似的问题sed

-一世 clobbers只读文件

简而言之, 'sed -i'将让你删除一个只读文件的内容,一般来说 -一世选项(请参阅调用)可以让您破坏受保护的文件。这不是一个bug,而是Unix文件系统的工作原理。

对文件的权限说明了该文件中的数据可能发生的情况,而目录上的权限则说明该目录中的文件列表会发生什么。sed -i“不会打开写入已经在磁盘上的文件。相反,它将在最终重新命名为原始名称的临时文件中工作:如果您重命名或删除文件,则实际上是修改目录的内容,因此操作取决于目录的权限,而不是文件。出于同样的原因,sed不让你使用-一世 在只读目录中的可写文件上,并且将在打破硬链接或符号链接时 -一世 用于这样的文件。

0a 不工作(给出错误)

没有第0行。0是一个特殊地址,仅用于处理脚本启动时的活动状态:如果您写入,并且第一行包含“0,/RE/1,/abc/dABC',那么该匹配将被忽略,因为地址范围必须至少跨越两行(禁止文件的结尾); 但你可能想要删除的每一行,直到第一个包括'ABC',这是获得的0,/abc/d

[a-z] 不区分大小写

你遇到地方的问题。POSIX要求[a-z] 使用当前语言环境的归类顺序 - 在C语言中,这意味着使用 strcoll(3)而不是strcmp(3)某些区域设置具有不区分大小写的排序规则,而其他区域设置则没有。

另一个问题是[a-z]尝试使用排序规则符号。这只会在GNU系统上使用 GNU libc的正则表达式匹配器而不是编译GNU sed 提供的一个例如,在丹麦地区,正则表达式^[a-z]$匹配字符串'AA',因为这是一个单一的整理符号,一个'和'之前'b“; “在西班牙语区域中的行为类似,或者”IJ“在荷兰语区域。

要解决这些问题,这可能会导致错误的shell脚本,设置LC_COLLATELC_CTYPE环境变量“C”。

s/.*// 不清除图案空间

如果您的输入流包含无效的多字节序列,则会发生这种情况。 POSIX要求这样的序列匹配“', 以便 '小号/.*//“不会像你所期望的那样清除模式空间。实际上,在大多数多字节语言环境(包括UTF-8语言环境)中,没有办法在脚本中间清除sed的缓冲区。因此,GNU sed提供了一个'z'命令(用于'zap')作为扩展名。

要解决这些问题,这可能会导致错误的shell脚本,设置LC_COLLATELC_CTYPE环境变量“C”。


附录A GNU自由文件许可证

版本1.3,2008年11月3日
版权所有©2000,2001,2002,2007,2008 Free Software Foundation,Inc. http://fsf.org/  每个人都可以复制和分发 本许可证文件的逐字副本,但不允许更改。 
  1. 前言

    本许可证的目的是使自由的手册,教科书或其他功能和有用的文件免费:确保每个人有效地自由地复制和重新分发它,无论是否在商业上或非商业上进行修改。其次,本许可证保留作者和出版商一种获得他们工作信誉的方式,而不被认为对其他人作出的修改负责。

    本许可证是一种“copyleft”,这意味着文件的衍生作品本身就是同样的自由。它补充了GNU通用公共许可证,该许可证是为免费软件设计的Copyleft许可证。

    我们设计了此许可证,以便将其用于免费软件手册,因为免费软件需要免费的文档:免费程序应随手册一起提供与软件相同的自由。但本许可证不限于软件手册; 它可以用于任何文本作品,无论主题或是否作为印刷本出版。我们建议本许可证主要用于作为指导或参考的作品。

  2. 适用性和定义

    本许可证适用于任何包含着作权人声明可以根据本许可证条款分发的任何媒体的任何手册或其他作品。此类通知授予全球无限制使用许可证,持续时间无限制,在本文所述条件下使用该工作。以下“文件”是指任何此类手册或作品。任何公众人士都是被许可人,被视为“你”。如果您以根据版权法许可的方式复制,修改或分发作品,则您接受许可。

    “文件”的“修改版本”是指包含文档或其一部分的任何作品,无论是逐字复制还是修改和/或翻译成其他语言。

    “中学部分”是本文件的命名附录或文件的前身部分,专门处理文档的出版者或作者与文档的整体主题(或相关事宜)的关系,并且不包含任何可能直接落入的内容在整个科目内。(因此,如果文件部分是数学教科书,则中学部分可能不会解释任何数学。)这种关系可能是与主题或相关事项或法律,商业,哲学,伦理学的历史联系的问题或政治立场。

    “不变部分”是指根据本许可证发布文件的通知中指定的标题为“不变部分”的某些辅助部分。如果一节不符合以上定义的Secondary,则不允许将其指定为Invariant。文件可能包含零个不变部分。如果文档没有标识任何不变的部分,那么没有。

    “封面文本”是指在文件根据本许可证发布的通知中列出的文本的一些简短段落作为封面文本或封底文本。封面文本最多可以有5个字,封底文字最多可以有25个字。

    文件的“透明”副本是指一种机器可读的副本,以规范可供公众使用的格式表示,适用于使用通用文本编辑器直接修改文档,或(对于由像素组成的图像)通用绘画程序或(用于图纸)一些广泛可用的绘图编辑器,并且适用于输入文本格式化器或自动翻译成适合于输入到文本格式化器的各种格式。以其他透明文件格式制作的副本不是透明的,其标记或不存在标记已被安排来阻止或阻止读者的后续修改。如果用于任何大量的文本,图像格式不是透明的。不透明的副本称为“不透明”。

    透明副本的适用格式示例包括无标记的纯ASCII,Texinfo输入格式,LaTeX输入格式,使用公开可用DTD的SGML或XML,以及为人为修改设计的符合标准的简单HTML,PostScript或PDF。透明图像格式的示例包括PNG,XCF和JPG。不透明格式包括专有格式,只能由专有字处理器,SGML或XML(通常不可用的DTD和/或处理工具)以及由某些字处理程序生成的机器生成的HTML,PostScript或PDF输出目的。

    “标题页”是指对于印刷的书籍,标题页面本身,以及需要容易地保存本许可证要求在标题页中显示的材料的以下页面。对于没有任何标题页的格式的作品,“标题页”是指在文本正文开头之前,最突出的工作标题外观的文字。

    “出版商”是指将文件副本分发给公众的任何个人或实体。

    “被命名的XYZ”部分是指文件的命名子单元,其标题或者是精确的XYZ,或者在以另一种语言翻译XYZ的文本之后的括号中包含XYZ。(这里XYZ表示下面提到的特定部分名称,例如“鸣谢”,“奉献”,“认可”或“历史”)。当您修改文档时,要保留此部分的“保留标题”,意味着根据这个定义,它仍然是一个“被命名的XYZ”部分。

    该文件可能包括声明本许可证适用于文档的通知旁的保修免责声明。这些保修条款免责声明被视为在本许可证中被引用参考,但仅限于免责声明:本免责声明可能存在的任何其他含义无效,对本许可证的含义没有任何影响。

  3. VERBATIM复制

    只要本许可证,版权声明和许可证声明对本文件适用的所有副本都被复制,并且不添加任何其他条件,您可以以任何媒体(商业或非商业)复制和分发文档。对本许可证。您不得使用技术措施阻止或控制您制作或分发的副本的阅读或进一步复制。但是,您可以接受补偿以换取副本。如果您分发足够数量的副本,您还必须遵守第3节中的条件。

    您也可以在上述相同条件下借出副本,您可以公开显示副本。

  4. 复制数量

    如果您发布文件的印刷版本(或通常印有封面的印刷品),编号超过100份,文件许可证通知要求封面文本,则必须将复印件全部包含在所有这些封面文本:前盖上的封面文本和封底上的封底文本。这两个封面也必须清楚和清晰地识别出您是这些副本的发行人。前盖必须呈现标题的所有单词,同样突出和可见。另外,您还可以在封面上添加其他材料。复制限于封面的变更,只要保存文件的标题并满足这些条件,就可以在其他方面视为逐字复制。

    如果任何一个封面所需的文本太庞大,无法容易地清理,您应该将列出的第一个(合理合理地放置)放在实际封面上,并将其余部分继续留在相邻的页面上。

    如果您发布或分发文档编号超过100的不透明副本,则必须包含机器可读的透明副本以及每个不透明的副本,或者在每个不透明的副本中或每个不透明的副本中指定一个计算机网络位置,使用公众可以使用公共标准网络协议进行下载,完整的透明文件副本,免费添加资料。如果您使用后一个选项,您必须采取相当谨慎的步骤,当您开始分发不透明份数量时,以确保此透明副本将保留在指定的位置,直到上一次分发后至少一年该版本的公开副本(直接或通过您的代理商或零售商)。

    请求但不要求您在重新分发大量副本之前联系文档的作者,以便他们有机会为您提供文档的更新版本。

  5. MODIFICATIONS

    您可以在上述第2节和第3节的条件下复制和分发文档的修改版本,前提是您根据本许可证发布修改版本,修改版本填写了文档的作用,从而授权分发和修改修改版本给谁拥有它的副本。此外,您必须在修改版本中执行以下操作:

    1. 在标题页(和封面,如果有的话)中使用不同于文档的标题以及以前版本的标题(如果有的话,应该在文档的“历史”部分中列出)。如果该版本的原始发行者有权限,则可以使用与之前版本相同的标题。
    2. 作为作者,标题页上列出了一个或多个负责修改版本修改的作者的个人或实体,连同文件的主要作者(所有主要作者,如果它少于五),除非他们释放你的这个要求。
    3. 作为发布商,“标题”页面上的“修改版本”的发布者的名称。
    4. 保留文件的所有版权声明。
    5. 为其他版权声明附近的修改添加适当的版权声明。
    6. 在版权声明后立即包括根据本许可证的条款授予公众许可使用修改版本的许可证通知,其格式如下面的附录所示。
    7. 在该许可证中保留通知文件许可证通知中给出的不变部分和所需封面文本的完整列表。
    8. 包括本许可证未经修改的副本。
    9. 保留标题为“历史”的部分,保留其标题,并添加一个项目,至少标明标题页上给出的修改版本的标题,年份,新作者和发行人。如果文档中没有“文档”中的“历史”部分,请在其标题页面上创建一个说明文档的标题,年份,作者和出版者,然后添加描述上一句所述的修改版本的项目。
    10. 保留文档中给出的网络位置(如果有的话)以公开访问文档的透明副本,以及文档中给出的基于之前版本的网络位置。这些可以放在“历史”部分。您可以省略在文档本身之前至少四年发布的作品的网络位置,或者它所引用的版本的原始发行者获得许可。
    11. 对于“致谢”或“奉献”的任何部分,保留该部分的标题,并在该部分中保留每个贡献者的确认和/或奉献的所有实质和基调。
    12. 保留文件的所有不变部分,在其文本和标题中保持不变。章节编号或等效项不被视为部分标题的一部分。
    13. 删除任何标题为“认可”的部分。此类部分可能不包括在修改版本中。
    14. 不要将任何现有部分重新标记为被授予“认可”或与任何不变部分产生冲突。
    15. 保留任何免责声明。

    如果修改后的版本包含新的前项部分或符合二级部分的附录,并且不包含从文档中复制的材料,则可以选择将这些部分中的一些或全部指定为不变量。为此,请将其标题添加到修改版本的许可证通知中的“不变部分”列表中。这些标题必须与任何其他章节标题不同。

    您可以添加一个标题为“认可”的部分,前提是它不仅包含各方修改的版本的签注,例如同行评议的声明,或者该文本已被组织批准为标准的权威定义。

    您可以添加一个最多五个词的段落作为封面文本,最多可以添加25个词作为封底文本,到修改版本的封面文本列表的末尾。通过(或通过任何一个实体的安排),可以添加前封面文本和封底文本之一的一段。如果文件已经包含了以前由您添加的同一封面的封面文本,或由代表您所代表的同一实体作出的安排,则不能添加另一封封; 但是您可以根据添加旧的发布者的明确许可来替换旧的。

    文件的作者和发行人不得通过本许可证授予使用其名称进行宣传或声明或暗示认可任何修改版本的许可。

  6. 组合文件

    您可以根据本许可证发布的其他文件,根据上述第4节所定义的条款将修改后的版本合并在一起,前提是您将所有原始文档的所有不变部分(未修改)全部包含在内,并将其全部列出作为您的许可证通知中组合工作的不变部分,并保留所有的保修免责声明。

    组合工作只需要包含该许可证的一个副本,并且可以用单个副本替换多个相同的不变部分。如果有多个具有相同名称但内容不同的不变部分,则通过在其末尾加上每个这样的部分的标题,如果已知的话,则在该部分的原始作者或出版商的名称中加上括号,否则为唯一号码。对组合工作的许可证通知中的“不变部分”列表中的部分标题进行相同的调整。

    在组合中,您必须将各种原始文档中的“历史记录”命名为“历史记录”。同样组合任何标题为“致谢”的部分,以及任何题为“奉献”的部分。您必须删除所有标题为“认可”的部分。

  7. 收集文件

    您可以制作由本许可证下发布的“文档”和其他文档组成的集合,并将该许可证的各个副本替换为包含在该集合中的单个副本的各种文档,前提是您遵循本许可证的规则在所有其他方面逐字复制每份文件。

    您可以从此类集合中提取单个文档,并根据本许可证单独分发该文档,前提是您将本许可证的副本插入到提取的文档中,并按照本许可证在所有其他方面逐字复制该文档。

  8. 积极参与独立工作

    如果由汇编而产生的版权不用于限制合法权利,则将文件或其衍生物与其他单独和独立的文件或作品在一个或多个存储或分发介质中或之间的汇编称为“汇总”的编辑用户超出了个人作品允许的范围。当文档包含在合并中时,本许可证不适用于本身并非本文的衍生作品的其他作品。

    如果第3条的封面文本要求适用于文件的这些副本,则如果文档少于整个合计的一半,则文档的封面文本可以放置在合并中的文档的封面上,或者如果文件是电子形式的电子等效的封面。否则,它们必须出现在打印的整个聚合体上。

  9. 翻译

    翻译被认为是一种修改,因此您可以根据第4节的条款分发文档的翻译。使用翻译替换不变部分需要其版权所有者的特别许可,但您可以包括部分或所有不变部分的翻译,以及这些不变部分的原始版本。您可以包括本许可证的翻译,以及文档中的所有许可证通知以及任何免责声明,前提是您还包括本许可证的原始英文版本以及这些通知和免责声明的原始版本。如果翻译与本许可证的原始版本或通知或免责声明之间存在分歧,则以原始版本为准。

    如果文件中的一部分被授予“鸣谢”,“奉献”或“历史”,则保留其标题(第1节)的要求(第4节)通常需要更改实际标题。

  10. 终止

    除非根据本许可证明确规定,否则您不得复制,修改,再授权或分发文档。任何其他方式复制,修改,再授权或分发的任何操作均为无效,并将自动终止您在本许可证下的权利。

    但是,如果您停止所有违反本许可证的行为,则您的特许版权所有人的许可证将暂时恢复(a),除非和直到版权所有者明确终止您的许可,否则(b)如果版权所有者失败在停止后60天内以合理的方式通知您违规。

    此外,如果版权所有者以合理的方式通知您违规行为,则特许版权持有人的许可将被永久恢复,这是您第一次收到该版权所有人违反本许可证(任何工作)的通知,您在收到通知后30天内解决违规行为。

    根据本节终止您的权利不会终止根据本许可证收到您的副本或权利的各方的许可。如果您的权利已被终止并未永久恢复,则收到部分或全部相同材料的副本不会给您任何使用权。

  11. 本许可证的未来版本

    自由软件基金会可能不定期地发布新版本的GNU自由文档许可证。这样的新版本将在精神上类似于现在的版本,但可能会有不同的细节来解决新的问题或疑虑。见 http://www.gnu.org/copyleft/

    许可证的每个版本都有一个区别的版本号。如果“文件”指定本许可证的特定编号版本“或任何更高版本”适用于此,您可以选择遵循指定版本或已发布的任何更新版本的条款和条件(不是作为草案)由自由软件基金会。如果文档没有指定本许可证的版本号,您可以选择自由软件基金会发布的任何版本(不是草稿)。如果文档指定代理可以决定是否可以使用本许可证的哪些版本,该代理的公开接受版本将永久授权您为文档选择该版本。

  12. 重新授权

    “大型多用户协作站点”(或“MMC站点”)是指任何出版可作版权作品的万维网服务器,也为任何人编辑这些作品提供了突出的设施。任何人都可以编辑的公共wiki就是这样一个服务器的例子。网站中包含的“大规模多作者协作”(或“MMC”)是指在MMC网站上发布的任何版权作品。

    “CC-BY-SA”是指由知识共享署(Creative Commons Corporation)发布的知识共享署名 - 相同方式3.0许可协议,Creative Commons Corporation是一家在加利福尼亚州旧金山拥有主要营业地点的非营利性公司,以及未来的Copyleft版本同一组织发布的许可证。

    “合并”是指作为另一个文档的一部分,全部或部分地发布或重新发布文档。

    如果根据本许可证获得许可,则MMC有资格获得重新认证,如果根据本许可证首次发布的所有作品,除了本MMC之外的其他地方,随后全部或部分纳入MMC,(1)没有涵盖文本或不变部分,以及(2)因此在2008年11月1日之前被合并。

    MMC网站的运营商可以在2009年8月1日之前的任何时间,在同一网站上重新发布CC-BY-SA网站中的MMC,前提是MMC有资格获得重新认证。

ADDENDUM:如何使用本许可证的文件

要在您所写的文档中使用本许可证,请在文档中包含许可证的副本,并在标题页面之后放置以下版权和许可证通知:

 版权(C) 年 你的名字 授权 根据GNU自由文件许可证1.3版 或自由软件基金会发布的任何更新版本的条款复制,分发和/或修改本文档;  没有不变的部分,没有封面文本,也没有封底 文本。许可证的副本包含在标题为“GNU  Free Documentation License”的部分。 

如果您有不变章节,封面文本和封底文本,请将“with ... Texts。”替换为:

 其中不变部分列出了他们的标题 前封面文本是列表,封面文本列表

如果您没有封面文本的不变章节,或三者的其他组合,请合并这两种替代方案以适应这种情况。

如果您的文档包含程序代码的不寻常的示例,我们建议您在您选择的免费软件许可证(如GNU通用公共许可证)下并行发布这些示例,以允许其在自由软件中使用。



概念指数

这是本手册中讨论的所有问题的一般索引,sed命令和命令行选项除外



向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI