该文件记录GNU 版本4.4 sed,一个流编辑器。
版权所有©1998-2017自由软件基金会
授权根据GNU自由文件许可证1.3版或自由软件基金会发布的任何更新版本的条款复制,分发和/或修改本文档; 没有不变的部分,没有封面文本,也没有封底文本。许可证的副本包含在题为“GNU自由文件许可证”的部分。
? 介绍: | 介绍 | |
? 调用sed: | 调用 | |
? sed脚本: | sed 脚本 | |
? sed地址: | 地址:选择行 | |
? sed正则表达式: | 正则表达式:选择文本 | |
? 高级sed: | 高级sed:循环和缓冲区 | |
? 示例: | 一些示例脚本 | |
? 限制: | GNU的限制和(非)限制 sed | |
? 其他资源: | 其他资源用于学习 sed | |
? 报告错误: | 报告错误 | |
? GNU免费文档许可证: | 复制并分享本手册 | |
? 概念指标: | 本手册中包含所有主题的菜单。 | |
? 命令和选项索引: | 具有所有sed命令和命令行选项的菜单。 |
sed是一个流编辑器。流编辑器用于对输入流(文件或流水线的输入)执行基本文本转换。虽然在某些方面类似于允许脚本编辑(例如ed) 的编辑器,sed只能通过输入一次,但效率更高。但是,它有sed能力在管道中过滤文本,特别区别于其他类型的编辑器。
本章介绍如何运行sed。sed 脚本和单个sed命令的详细信息将在下一章讨论。
? 概述: | ||
? 命令行选项: | ||
? 退出状态: |
通常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将输出写入标准输出。使用-一世在现场编辑文件而不是打印到标准输出。又见W和s///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
调用的完整格式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。
--posixGNU 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, - 表达, 要么 - 文件 选项在命令行中给出,则命令行上的第一个非选项参数被视为要执行的脚本。
如果在处理上述内容后仍有任何命令行参数,这些参数将被解释为要处理的输入文件的名称。 文件名“ - '指标准输入流。如果没有指定文件名,将处理标准输入。
退出状态为零表示成功,非零值表示失败。GNU sed返回以下退出状态错误值:
0成功完成
1无效的命令,无效的语法,无效的正则表达式或与之一起使用的 GNU sed扩展命令--posix。
2在命令行上指定的一个或多个输入文件无法打开(例如,如果找不到文件或拒绝读取权限)。处理继续与其他文件。
4I / O错误或运行时严重的处理错误, GNU sed立即中止。
另外,该命令q和Q可用于终止 sed与自定义退出代码值(这是一个GNU sed扩展名):
$ echo | sed'Q42'; echo $? 42
? sed脚本概述: | sed 脚本概述 | |
? sed命令列表: | sed 命令摘要 | |
? “s”命令: | sed的瑞士军刀 | |
? 常用命令: | 经常使用的命令 | |
? 其他命令: | 不常用的命令 | |
? 编程命令: | sed大师 命令 | |
? 扩展命令: | 特定于GNU的命令 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
命令a,c,i,由于它们的语法,不能被随后工作作为命令分隔符分号,因此应当用换行被终止或者被放置在的末端脚本或脚本文件。命令之前也可以带有可选的非空白字符。请参阅多命令语法。
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, t,T)。
该s命令(如替代)可能是最重要的sed,有很多不同的选择。该s命令的语法是's / regexp / replacement / flags”。
它的基本概念很简单:该s命令尝试将模式空间与提供的正则表达式regexp匹配; 如果匹配成功,则匹配的模式空间的那部分被替换替换。
有关regexp语法的详细信息,请参阅正则表达式地址。
所述替换可以包含(?是一个从1到9,包括端点)的引用,这指的是包含在之间的匹配的所述部分?个 及其匹配。此外,替换可以包含 引用模式空间的整个匹配部分的未转义字符。 \n\(\)&
该/ 字符可通过任何给定的内的任何其他单个字符被均匀地取代s命令。的/ 字符(或任何其他字符代替它使用)可以在出现正则表达式或替换 仅当它是由前面\的字符。
最后,作为一个GNU sed扩展,可以包括由一个反斜杠和一个字母的特殊序列 L,l,U,u,或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如果进行替换,则打印新的图案空间。
注意:当指定了选项p和e选项时,两者的相对排序产生非常不同的结果。一般来说,ep(评估然后打印)是你想要的,但另一方面操作可能对调试是有用的。因此,当前版本的GNU sed特别解释p了前后选项的存在,e在评估之前和之后 打印模式空间,而一般来说,该s命令的标志只显示一次。尽管如此,这种行为可能会在将来的版本中发生变化。
w filename如果进行替换,则将结果写入命名文件。作为GNU sed扩展,支持两个特殊的文件名值:的/ dev /标准错误,将结果写入标准错误,以及 的/ dev /标准输出,写入标准输出。3
e该命令允许从shell命令将输入管道转换为模式空间。如果进行替换,则执行在模式空间中找到的命令,并将其空格替换为其输出。尾随的换行被压制; 如果要执行的命令包含NUL字符,则结果未定义。这是一个GNU sed扩展。
I iI正则表达式匹配的修饰符是一个GNU 扩展,它使sed匹配正则表达式以不区分大小写的方式。
M mM正则表达式匹配的修饰符是GNU sed 扩展,它指示GNU sed在多行模式下匹配正则表达式。修饰符分别引起^和$匹配换行符之后的空字符串(除正常行为之外),换行符之前的空字符串。有一些特殊的字符序列(\`和\')始终与缓冲区的开头或结尾相匹配。另外,在多行模式下,句点字符与新行字符不匹配。
如果你完全使用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
打印图案空间(到标准输出)。此命令通常仅与该命令配合使用-n 命令行选项。
示例:仅打印第二个输入行:
$ seq 3 | sed -n 2p 2
如果未禁用自动打印,请打印图案空间,然后,无论如何使用下一行输入替换图案空间。如果没有更多的输入,则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
一组命令可之间被封闭 {和}字符。当您希望通过单个地址(或地址范围)匹配来触发一组命令时,这特别有用。
示例:执行替换然后打印第二个输入行:
$ seq 3 | sed -n'2 {s / 2 / X /; p}' X
虽然可能比上一节更少使用,但是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”
在一行之前插入文字。这是标准命令的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”
用文字代替行。这是标准命令的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交换保留和模式空格的内容。
在大多数情况下,使用这些命令表明,您可能更喜欢像awk Perl 这样的编程。但偶尔有人坚持坚持sed,这些命令可以使一个人写一个非常复杂的脚本。
: label[无地址]
指定分支命令的标签位置。在所有其他方面,无操作。
b label无条件分支到标签。该标签可以被省略,在这种情况下,在下一个周期开始。
t label只有当自上一条输入行被读取或有条件分支以来已成功执行ubstitution时,才能进行标记s。该标签可以被省略,在这种情况下,在下一个周期开始。
这些命令是特定于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命令一样,具有特殊的价值的/ 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语言环境)中,没有可移植的方式清除脚本中间的缓冲区。
在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
的{,},b,t,T,:命令可以用分号分隔(这是一个非便携式GNU sed扩展名)。
$ seq 4 | sed'{1d; 3d}' 2 4 $ seq 6 | SED '{1D; 3D};图5d' 2 4 6
在使用的标签b,t,T,:指令被读取,直到一个分号。领先和尾随的空白被忽略。在下面的例子中,标签是“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
以下命令不能用分号分隔,需要换行符:
a,c,i(追加/变更/插入)所有字符以下a,c,i命令被作为追加/变更/插入的文本。使用分号会导致不良结果:
$ seq 2 | sed'1aHello; 2D” 1 您好; 2d 2
使用命令分开 -e 或换行:
$ seq 2 | sed -e 1aHello -e 2d 1 Hello $ seq 2 | SED '1aHello 2D' 1 你好
请注意,指定要添加的文本('你好“)后a,c,i本身就是一个GNU sed扩展。符合POSIX标准的便携式解决方案是:
$ seq 2 | SED '1A \ 你好 2D' 1 你好
所有字符“#直到下一个换行符被忽略。
$ seq 3 | sed'#这是一个评论; 2D” 1 2 3 $ SEQ 3 | SED '#这是一条评论 2D' 1 3
的r,R,w,W命令解析的文件名,直至行尾。如果找到空格,注释或分号,它们将被包含在文件名中,导致意想不到的结果:
$ 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在自动忽略读/写错误 r,R,w,W命令(如文件丢失)。在以下示例中,sed尝试读取名为“hello.txt; ?”。文件丢失,错误被忽略:
$ echo x | sed'1rhello.txt; N” X
e命令之后的任何字符直到行尾都将发送到shell。如果找到空格,注释或分号,它们将被包含在shell命令中,导致意想不到的结果:
$ echo a | SED '1E触摸富#酒吧' 一个 $ LS -1 富#酒吧 $回显| sed'1e touch foo; s / a / b /' sh:1:s / a / b /:找不到 a
在替换命令中,w标志将替换结果写入文件,并且该e标志以shell命令执行归属结果。与r/R/w/W/e命令一样,这些必须用换行符终止。如果找到空格,注释或分号,它们将被包含在shell命令或文件名中,从而导致意想不到的结果:
$ echo a | SED的/ A / B / w1.txt#富' b $ LS -1 的1.txt#FOO
? 地址概述: | 地址概述 | |
? 数字地址: | 按数字选择行 | |
?正则表达式地址: | 通过文本匹配选择行 | |
? 范围地址: | 选择一系列行 |
地址确定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
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
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”
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 ?
M正则表达式匹配的修饰符是GNU sed 扩展,它指示GNU sed在多行模式下匹配正则表达式。修饰符分别引起^和$匹配换行符之后的空字符串(除正常行为之外),换行符之前的空字符串。有一些特殊的字符序列(\`和\')始终与缓冲区的开头或结尾相匹配。另外,在多行模式下,句点字符与新行字符不匹配。
可以通过指定两个以逗号(,)分隔的地址来指定地址范围。地址范围匹配从第一个地址匹配的行开始,直到第二个地址匹配(包括):
$ 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和?以下行ADDR1。
$ seq 10 | SED -N '6,+ 2P' 6 7 8
addr1可以是行号或正则表达式。
addr1,~N匹配addr1和addr1 之后的行,直到输入行号为N的倍数的下一行。以下命令从第6行开始,直到下一行为4的倍数(即第8行):
$ seq 10 | SED -n '6,?4P' 6 7 8
addr1可以是行号或正则表达式。
? 正则表达式概述: | 正则表达式概述 sed | |
? BRE vs ERE: | 基本(BRE)和扩展(ERE)正则表达式语法 | |
? BRE语法: | 基本正则表达式语法概述 | |
? ERE语法: | 扩展正则表达式语法概述 | |
? 字符类和括号表达式: | ||
?正则表达式扩展: | 附加正则表达式命令 | |
? 反向引用和子表达式: | 反向引用和子表达式 | |
? 逃离: | 指定特殊字符 | |
? 区域注意事项: |
要知道如何使用sed,人们应该了解的正则表达式(正则表达式的简称)。正则表达式是从左到右匹配主题字符串的模式。大多数字符是 普通的:它们代表自己的模式,并且匹配相应的字符。正则表达式在sed两个斜杠之间指定。
以下命令打印包含单词“你好“:
sed -n'/ hello / p'
上面的例子相当于这个grep命令:
grep'你好
正则表达式的力量来自于在模式中包含替代和重复的能力。这些是通过使用特殊字符在模式中编码的,这些字符不代表自己,而是以某种特殊方式进行解释。
^正则表达式中的字符(插入符号)与行的开头匹配。字符.(点)匹配任何单个字符。以下sed命令匹配并打印以字母“b',其次是任何一个字符,其次是字母'?“:
$ printf“%s \ n”abode bad bed bit bid byte body | sed -n'/ ^ bd / p' 坏 床 招标 机构
以下部分说明正则表达式中特殊字符的含义和用法。
基本和扩展正则表达式是指定模式语法的两个变体。基本正则表达式(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 |
以下是正则表达式语法的简要说明sed。
char一个普通字符与自己相匹配。
*匹配上一个正则表达式的零个或多个匹配实例的序列,该正则表达式必须是普通字符,前缀为\a .,分组的正则表达式(见下文)或括号表达式的特殊字符。作为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\}匹配i和j,包括序列。
\{i,\}匹配大于或等于i序列。
\(regexp\)将内部正则表达式组合为一个整体,这用于:
匹配regexp1或regexp2。使用括号来使用复杂的替代正则表达式。匹配过程从左到右依次尝试每个替代,并且使用成功的第一个。这是一个GNU扩展。
regexp1regexp2匹配regexp1和regexp2的连接。级联地结合不同于更紧密\|,^和 $,但较不紧密比其他正则表达式运算符。
\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个字符的字符串的开头,最后一个是'一个”。
基本和扩展正则表达式的唯一区别在于几个字符的行为:?'''+',括号,大括号('{}'),和'|”。虽然基本的正则表达式要求将它们转义为特殊字符,但如果您希望它们与文字字符匹配,则使用扩展正则表达式时,必须将其转义。“|因为'\ |'是一个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”。
甲括号表达式是由包围字符的列表'['和']”。它匹配该列表中的任何单个字符; 如果列表的第一个字符是插入符号'^',那么它匹配任何不在列表中的字符。例如,以下命令将替换“灰色' 要么 '灰色'与'蓝色“:
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
字母数字字符: '[:α:]'和'[:数字:]“; 在里面 '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内确认名单。看到逃生。
“[“表示开放的整理符号。
“]“代表紧密整理符号。
“[=“表示开放等价类。
“=]“代表密切的等价类。
“[:“表示打开的字符类符号,后面应该有一个有效的字符类名称。
“:]“代表关闭字符类符号。
以下序列在正则表达式中具有特殊含义(在地址和s命令中使用)。
这些可以用于 基本和扩展 正则表达式(即,使用或不使用-E/-r 选项)。
\w匹配任何“单词”字符。“字”字符是任何字母或数字或下划线字符。
$ echo“abc% - = def”。| sed / / w / X / g'XXX% - = XXX。
匹配任何“非字”字符。
$ echo“abc% - = def”。| sed的/ \ W / X / g'abcXXXXXdefX
匹配单词边界; 如果左边的字符是“字”字符,并且右边的字符是“非字”字符,则反之亦然。
$ echo“abc% - = def”。| sed的/ \ b / X / g'XabcX% - = XdefX。
匹配到处都是字边界; 如果左边的字符和右边的字符既是“字”字符也可以是“非字”两个字符,那就是匹配。
$ echo“abc% - = def”。| sed的/ \ w / X / g'aXbXc X%XX = X dXeXf.X
匹配空格字符(空格和制表符)。嵌入模式/保持空格的换行符也将匹配:
$ echo“abc% - = def”。| sed / s / X / g'abcX% - = Xdef。
匹配非空格字符。
$ 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
仅匹配模式空间的结尾。这与$多行模式不同。
反向引用是指匹配的正则表达式的前一部分的正则表达式命令。反向引用使用反斜杠和单个数字(例如“\ 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 文件'),反向引用是每个表达式的本地。
直到本章,我们才遇到过“\ ^“,它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由于与现有的“字边界”的冲突,“(退格)被忽略。
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
? 执行周期: | 如何sed工作 | |
? 保持和模式缓冲区: | ||
? 多线技术: | 使用D,G,H,N,P处理多行 | |
? 分支和流量控制: |
下一个:保持和模式缓冲区,向上:高级sed [ 目录 ] [ 索引 ]
sed维护两个数据缓冲区:活动模式空间和辅助保持空间。两者最初都是空的。
sed通过在每行输入上执行以下循环来操作:首先,sed从输入流中读取一行,删除任何尾随的换行符,并将其放在模式空间中。然后执行命令; 每个命令可以具有与之相关联的地址:地址是一种条件代码,只有在执行命令之前验证条件时才执行命令。
当脚本结束到达时,除非 -n选项正在使用中,模式空间的内容将打印到输出流中,如果删除尾随的换行符,则返回。7然后下一个循环开始下一个输入行。
除非特殊命令(如“?'),在两个周期之间删除模式空间。另一方面,保持空间将数据保留在周期之间(参见命令'H'''H'''X'''G'''G'在两个缓冲区之间移动数据)。
去做
多行可以如一个缓冲器使用被处理 D,G,H,N,P。它们类似于其小写同行(d,g, h,n,p),所不同的是这些命令追加或同时尊重嵌入换行符减去数据-允许从图案添加和删除行和保持的空间。
它们的操作如下:
D从模式空间中删除行直到第一个换行符,然后重新启动循环。
G将行从保留空间追加到模式空间,并在其前加上换行符。
H将线从模式空间追加到保持空间,并在其前面加上换行符。
N将行从输入文件追加到模式空间。
P从图案空间打印到第一个换行符。
以下示例说明了操作N和 D命令:
$ seq 6 | sed -n'N; l; D' 1 \ n2 $ 2 \ n3 $ 3 \ n4 $ 4 \ n5 $ 5 \ n6 $
处理文本块(例如段落(而不是逐行))的常用技术是使用以下构造:
sed'/./{H;$!d}; X ; S / REGEXP / REPLACEMENT /”
以下示例演示了此技术:
$ 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
有关更多注释的示例,请参阅跨多行的文本搜索 和行长度调整。
分支命令b,t并且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
的b,t并且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
分支通常用n或N命令来补充:两个命令都将下一个输入行读入模式空间,而无需等待重新启动循环。在读取下一个输入行之前,n 打印当前图案空间,然后将其排空,同时N将一个换行符和下一个输入行附加到模式空间。
考虑以下两个例子:
$ seq 3 | sed':x; n; BX” 1 2 3 $ SEQ 3 | sed':x; N; BX” 1 2 3
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”
作为使用分支的现实世界示例,请考虑通常用于对电子邮件进行编码的引用可打印文件的情况 。在这些文件中,长行被分割并标有一个软线路断点, 由一个单一的“='字符在行尾:
$ 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 并将删除图案空间内容直到第一个新行。(如需了解更多有关N,P并D命令看多线技术)。
$ sed':x; $!N; s / = \ n //; tx; P; D'jaques.txt 所有的世界都是一个舞台, 所有的男人和女人只是玩家: 他们有他们的出口和入口; 一个人在他的时间玩很多部分。
有关更多线连接示例,请参阅连接线。
这里有一些sed脚本可以指导您掌握掌握的技巧 sed。
有用的一线
|
||
---|---|---|
? 连线: | ||
一些奇异的例子:
|
||
? 定心线: | ||
? 增加一个数字: | ||
? 将文件重命名为小写: | ||
? 打印bash环境: | ||
? 反转字符串: | ||
? 跨多行的文本搜索: | ||
? 线长调整: | ||
模拟标准实用程序
|
||
? tac: | 反向文件行 | |
? 猫: | 编号行 | |
? cat -b: | 编号非空白行 | |
? wc -c: | 计数字符 | |
? wc -w: | 计数字 | |
? wc -l: | 计数线 | |
? 头: | 打印第一行 | |
? 尾巴: | 打印最后一行 | |
? uniq: | 使重复行唯一 | |
? uniq -d: | 打印重复的输入行 | |
? uniq -u: | 删除所有重复的行 | |
? cat -s: | 挤压空白线 |
下一步:定心线,向上:示例 [ 内容 ] [ 索引 ]
本节使用N,D并P命令以处理多行,并且b与t分支命令。请参阅多线技术和分支和流控制。
加入特定行(例如,如果第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'
这个脚本将文件的所有行都放在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 /
这个脚本是演示如何进行算术的几个脚本之一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 /
这是一个非常奇怪的用法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
该脚本从setBourne-shell命令的输出中剥离shell函数的定义。
#!/ bin / sh的
set | sed -n' :x
#如果没有发生'=()'打印并加载下一行 / =()/!{p; b; } /()$ /!{p; b; }
#可能启动函数部分 #保存行,以防万一这是一个var像FOO =“()” h
#如果下一行有一个括号,我们退出,因为 #没有任何东西在函数 n / ^ {/ q之后
打印旧行 x; p
现在在新线上工作 x; bx '
该脚本可用于反转行中字符的位置。该技术一次移动两个字符,因此它比更直观的实现更快。
注意tx在标签定义之前的命令。这通常需要重置由该t命令测试的标志。
想象力的读者将会找到这个脚本的用法。一个例子是扭转输出banner。9
#!/ usr / bin / sed -f /../!b
#反转一行 开始在两个换行符之间嵌入行 s /^.*$/ \ &\ /
#移动第一个字符在结尾。正则表达式匹配直到 #在标记之间有零个或一个字符 tx :x s / \(\ n。\)\(。* \)\(。\ n \)/ \ 3 \ 2 \ 1 / tx
#删除换行符 s / \ n // g
本节使用N和D命令来搜索跨越多行连续字。参见多线技术。
这些例子涉及在文件中发现双重发生的词语。
在一行中寻找重复的单词是容易使用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 这是智慧的时代,
当双字跨越两行时,上述正则表达式将不会找到它们grep并sed逐行操作。
通过使用N和D命令,sed可以在多行上应用正则表达式(即,多行存储在模式空间中,正则表达式在其上工作):
$ cat two-cities-dup2.txt 这是最好的时代,这是 最糟糕的时代,那就是 智慧的时代, 那是愚昧的时代, $ sed -En'{N; / \ b(\ w +)\ s + \ 1 \ b / {=; p}; D}'两城 - dup2.txt 3 最糟糕的时候,那是 智慧的时代,
请参阅GNU coreutils手册使用的替代解决方案 tr -s和uniq在 https://gnu.org/s/coreutils/manual/html_node/Squeezing-and-deleting.html。
本节使用N和D命令来搜索跨越多行的连续词,以及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 这是最好的时代, 这是最糟糕的时代, 那是智慧的时代, 那是愚昧的时代,
两个示例使用类似的结构:
这一个开始一系列完全无用(但有趣的)脚本,仿效各种Unix命令。这尤其是一种tac工作。
请注意,在GNU 以外的实现中,sed 此脚本可能容易溢出内部缓冲区。
#!/ usr / bin / sed -nf #反转所有行输入,即第一行成为最后,...
#从第二行,缓冲区(其中包含所有以前的行) #是*附加*到当前行,所以顺序将被反转 1!G
#在最后一行我们完成了 - 打印一切 $ p
#店面的一切对缓冲区再次 ^ h
这个脚本取代“猫“; 实际上它的输出格式与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 隐式添加的换行符
仿效'猫-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
这个脚本显示了另一种做算术的方式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
这个脚本与前一个脚本几乎相同,一旦这行上的每个单词被转换成一个单一的“一个'(在前面的脚本中,每封信都改为“一个“)。
有趣的是,真正的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
现在没有什么奇怪的事情,因为sed给我们'wc -l'功能免费!看:
#!/ usr / bin / sed -nf $ =
这个脚本可能是最简单的有用sed脚本。显示前10行输入; 显示的行数正好在q命令之前。
#!/ usr / bin / sed -f 10q
打印最后的n行而不是第一行更复杂,但确实可能。 n在第二行编码,在爆炸字符之前。
该脚本类似于tac脚本,它将最终输出保留在保留空间中,并将其打印到最后:
#!/ usr / bin / sed -nf
1!{; H; G; } 1,10!s / [^ \ n] * \ n // $ p h
主要是脚本保持10行的窗口,并通过添加一行并删除最旧的(第二行的替换命令像D命令一样工作但不重新启动循环)来滑动它。
“滑动窗口”技术是编写高效和复杂sed脚本的非常强大的方式,因为像P手动执行的命令 需要大量的工作。
为了介绍这一技术,在本章的其余部分中得到充分的阐述N,P 并且基于这一点和D命令,这里是一个tail 使用简单的“滑动窗口” 的实现。
这看起来很复杂,但实际上工作与最后一个脚本相同:在我们踢了适当数量的行后,我们停止使用保持空间来保持跨行状态,而是使用N和D滑动模式空间一行:
#!/ usr / bin / sed -f
1h 2,10 {; H; G; } $ q 1,9d N D
注意在前十行输入之后,第一行,第二行和第四行如何处于非活动状态。之后,所有的脚本都是:退出最后一行输入,将下一个输入行附加到模式空间,并删除第一行。
这是在本领域使用的一个例子N,P 和D命令,可能是最难以掌握。
#!/ usr / bin / sed -f h
:b #在最后一行打印并退出 $ b N /^\(.*\)\n\1$/ { #两行相同。撤消#n 命令的效果。 g bb }
#如果N命令添加了最后一行,请打印并退出 $ b
线条不一样; 打印第一个,然后回去 #在第二个工作。 P D
可以看到,我们使用P和维护一个2行窗口D。这种技术常用于高级sed脚本。
此脚本仅打印重复的行,如“uniq -d”。
#!/ usr / bin / sed -nf
$ b N /^\(.*\)\n\1$/ { #打印第一个重复行 s /.* \ n // p
#循环直到我们得到一个不同的行 :b $ b N /^\(.*\)\n\1$/ { s /.* \ n // bb } }
#最后一行不能跟着重复的 $ b
#找到不同的。将它单独放在模式空间 #中,并返回到顶部,狩猎其重复的 D
此脚本仅打印独特的行,如“uniq -u”。
#!/ usr / bin / sed -f
#搜索一个重复的行---直到那个,打印你找到的。 $ b N /^\(.*\)\n\1$/!{ P D }
:c #在模式空间中有两条相等的行。在 文件的#端,我们只需退出 $ d
#否则,我们继续读取行,N直到我们 找到不同的一个/ /。* \ n // N /^\(.*\)\n\1$/ { bc }
#删除重复行 #的最后一个实例,然后返回到顶部 D
作为最后一个例子,这里有三个脚本,其复杂性和速度越来越高,实现与“猫“那就是挤压空白线。
第一个在开始和结尾留下一个空白行,如果有一些已经。
#!/ 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
对于那些想要编写可移植sed脚本的人,请注意,已知某些实现将线路长度(对于模式和保持空间)限制为不超过4000字节。的POSIX标准规定,符合sed 实现应支持至少8192米字节行的长度。 GNU sed在线长度上没有内置限制; 只要它可以malloc()更多(虚拟)内存,只要你喜欢,你可以喂养或构建线条。
然而,递归用于处理子模式和无限期重复。这意味着可用的堆栈空间可能会限制某些模式可以处理的缓冲区的大小。
有关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开发人员维护 。
向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”的内容。是的,这在原则上是足够的信息来寻找错误,但这不是一个非常实际的前景。
以下是几个常见的错误,不是错误。
大多数版本的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来删除任何一个 abc或def。虽然这样工作,直到 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_COLLATE和LC_CTYPE环境变量“C”。
s/.*// 不清除图案空间如果您的输入流包含无效的多字节序列,则会发生这种情况。 POSIX要求这样的序列不匹配“。', 以便 '小号/.*//“不会像你所期望的那样清除模式空间。实际上,在大多数多字节语言环境(包括UTF-8语言环境)中,没有办法在脚本中间清除sed的缓冲区。因此,GNU sed提供了一个'z'命令(用于'zap')作为扩展名。
要解决这些问题,这可能会导致错误的shell脚本,设置LC_COLLATE和LC_CTYPE环境变量“C”。
版权所有©2000,2001,2002,2007,2008 Free Software Foundation,Inc. http://fsf.org/ 每个人都可以复制和分发 本许可证文件的逐字副本,但不允许更改。
本许可证的目的是使自由的手册,教科书或其他功能和有用的文件免费:确保每个人有效地自由地复制和重新分发它,无论是否在商业上或非商业上进行修改。其次,本许可证保留作者和出版商一种获得他们工作信誉的方式,而不被认为对其他人作出的修改负责。
本许可证是一种“copyleft”,这意味着文件的衍生作品本身就是同样的自由。它补充了GNU通用公共许可证,该许可证是为免费软件设计的Copyleft许可证。
我们设计了此许可证,以便将其用于免费软件手册,因为免费软件需要免费的文档:免费程序应随手册一起提供与软件相同的自由。但本许可证不限于软件手册; 它可以用于任何文本作品,无论主题或是否作为印刷本出版。我们建议本许可证主要用于作为指导或参考的作品。
本许可证适用于任何包含着作权人声明可以根据本许可证条款分发的任何媒体的任何手册或其他作品。此类通知授予全球无限制使用许可证,持续时间无限制,在本文所述条件下使用该工作。以下“文件”是指任何此类手册或作品。任何公众人士都是被许可人,被视为“你”。如果您以根据版权法许可的方式复制,修改或分发作品,则您接受许可。
“文件”的“修改版本”是指包含文档或其一部分的任何作品,无论是逐字复制还是修改和/或翻译成其他语言。
“中学部分”是本文件的命名附录或文件的前身部分,专门处理文档的出版者或作者与文档的整体主题(或相关事宜)的关系,并且不包含任何可能直接落入的内容在整个科目内。(因此,如果文件部分是数学教科书,则中学部分可能不会解释任何数学。)这种关系可能是与主题或相关事项或法律,商业,哲学,伦理学的历史联系的问题或政治立场。
“不变部分”是指根据本许可证发布文件的通知中指定的标题为“不变部分”的某些辅助部分。如果一节不符合以上定义的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节中的条件。
您也可以在上述相同条件下借出副本,您可以公开显示副本。
如果您发布文件的印刷版本(或通常印有封面的印刷品),编号超过100份,文件许可证通知要求封面文本,则必须将复印件全部包含在所有这些封面文本:前盖上的封面文本和封底上的封底文本。这两个封面也必须清楚和清晰地识别出您是这些副本的发行人。前盖必须呈现标题的所有单词,同样突出和可见。另外,您还可以在封面上添加其他材料。复制限于封面的变更,只要保存文件的标题并满足这些条件,就可以在其他方面视为逐字复制。
如果任何一个封面所需的文本太庞大,无法容易地清理,您应该将列出的第一个(合理合理地放置)放在实际封面上,并将其余部分继续留在相邻的页面上。
如果您发布或分发文档编号超过100的不透明副本,则必须包含机器可读的透明副本以及每个不透明的副本,或者在每个不透明的副本中或每个不透明的副本中指定一个计算机网络位置,使用公众可以使用公共标准网络协议进行下载,完整的透明文件副本,免费添加资料。如果您使用后一个选项,您必须采取相当谨慎的步骤,当您开始分发不透明份数量时,以确保此透明副本将保留在指定的位置,直到上一次分发后至少一年该版本的公开副本(直接或通过您的代理商或零售商)。
请求但不要求您在重新分发大量副本之前联系文档的作者,以便他们有机会为您提供文档的更新版本。
您可以在上述第2节和第3节的条件下复制和分发文档的修改版本,前提是您根据本许可证发布修改版本,修改版本填写了文档的作用,从而授权分发和修改修改版本给谁拥有它的副本。此外,您必须在修改版本中执行以下操作:
如果修改后的版本包含新的前项部分或符合二级部分的附录,并且不包含从文档中复制的材料,则可以选择将这些部分中的一些或全部指定为不变量。为此,请将其标题添加到修改版本的许可证通知中的“不变部分”列表中。这些标题必须与任何其他章节标题不同。
您可以添加一个标题为“认可”的部分,前提是它不仅包含各方修改的版本的签注,例如同行评议的声明,或者该文本已被组织批准为标准的权威定义。
您可以添加一个最多五个词的段落作为封面文本,最多可以添加25个词作为封底文本,到修改版本的封面文本列表的末尾。通过(或通过任何一个实体的安排),可以添加前封面文本和封底文本之一的一段。如果文件已经包含了以前由您添加的同一封面的封面文本,或由代表您所代表的同一实体作出的安排,则不能添加另一封封; 但是您可以根据添加旧的发布者的明确许可来替换旧的。
文件的作者和发行人不得通过本许可证授予使用其名称进行宣传或声明或暗示认可任何修改版本的许可。
您可以根据本许可证发布的其他文件,根据上述第4节所定义的条款将修改后的版本合并在一起,前提是您将所有原始文档的所有不变部分(未修改)全部包含在内,并将其全部列出作为您的许可证通知中组合工作的不变部分,并保留所有的保修免责声明。
组合工作只需要包含该许可证的一个副本,并且可以用单个副本替换多个相同的不变部分。如果有多个具有相同名称但内容不同的不变部分,则通过在其末尾加上每个这样的部分的标题,如果已知的话,则在该部分的原始作者或出版商的名称中加上括号,否则为唯一号码。对组合工作的许可证通知中的“不变部分”列表中的部分标题进行相同的调整。
在组合中,您必须将各种原始文档中的“历史记录”命名为“历史记录”。同样组合任何标题为“致谢”的部分,以及任何题为“奉献”的部分。您必须删除所有标题为“认可”的部分。
您可以制作由本许可证下发布的“文档”和其他文档组成的集合,并将该许可证的各个副本替换为包含在该集合中的单个副本的各种文档,前提是您遵循本许可证的规则在所有其他方面逐字复制每份文件。
您可以从此类集合中提取单个文档,并根据本许可证单独分发该文档,前提是您将本许可证的副本插入到提取的文档中,并按照本许可证在所有其他方面逐字复制该文档。
如果由汇编而产生的版权不用于限制合法权利,则将文件或其衍生物与其他单独和独立的文件或作品在一个或多个存储或分发介质中或之间的汇编称为“汇总”的编辑用户超出了个人作品允许的范围。当文档包含在合并中时,本许可证不适用于本身并非本文的衍生作品的其他作品。
如果第3条的封面文本要求适用于文件的这些副本,则如果文档少于整个合计的一半,则文档的封面文本可以放置在合并中的文档的封面上,或者如果文件是电子形式的电子等效的封面。否则,它们必须出现在打印的整个聚合体上。
翻译被认为是一种修改,因此您可以根据第4节的条款分发文档的翻译。使用翻译替换不变部分需要其版权所有者的特别许可,但您可以包括部分或所有不变部分的翻译,以及这些不变部分的原始版本。您可以包括本许可证的翻译,以及文档中的所有许可证通知以及任何免责声明,前提是您还包括本许可证的原始英文版本以及这些通知和免责声明的原始版本。如果翻译与本许可证的原始版本或通知或免责声明之间存在分歧,则以原始版本为准。
如果文件中的一部分被授予“鸣谢”,“奉献”或“历史”,则保留其标题(第1节)的要求(第4节)通常需要更改实际标题。
除非根据本许可证明确规定,否则您不得复制,修改,再授权或分发文档。任何其他方式复制,修改,再授权或分发的任何操作均为无效,并将自动终止您在本许可证下的权利。
但是,如果您停止所有违反本许可证的行为,则您的特许版权所有人的许可证将暂时恢复(a),除非和直到版权所有者明确终止您的许可,否则(b)如果版权所有者失败在停止后60天内以合理的方式通知您违规。
此外,如果版权所有者以合理的方式通知您违规行为,则特许版权持有人的许可将被永久恢复,这是您第一次收到该版权所有人违反本许可证(任何工作)的通知,您在收到通知后30天内解决违规行为。
根据本节终止您的权利不会终止根据本许可证收到您的副本或权利的各方的许可。如果您的权利已被终止并未永久恢复,则收到部分或全部相同材料的副本不会给您任何使用权。
自由软件基金会可能不定期地发布新版本的GNU自由文档许可证。这样的新版本将在精神上类似于现在的版本,但可能会有不同的细节来解决新的问题或疑虑。见 http://www.gnu.org/copyleft/。
许可证的每个版本都有一个区别的版本号。如果“文件”指定本许可证的特定编号版本“或任何更高版本”适用于此,您可以选择遵循指定版本或已发布的任何更新版本的条款和条件(不是作为草案)由自由软件基金会。如果文档没有指定本许可证的版本号,您可以选择自由软件基金会发布的任何版本(不是草稿)。如果文档指定代理可以决定是否可以使用本许可证的哪些版本,该代理的公开接受版本将永久授权您为文档选择该版本。
“大型多用户协作站点”(或“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有资格获得重新认证。
要在您所写的文档中使用本许可证,请在文档中包含许可证的副本,并在标题页面之后放置以下版权和许可证通知:
版权(C) 年 你的名字。 授权 根据GNU自由文件许可证1.3版 或自由软件基金会发布的任何更新版本的条款复制,分发和/或修改本文档; 没有不变的部分,没有封面文本,也没有封底 文本。许可证的副本包含在标题为“GNU Free Documentation License”的部分。
如果您有不变章节,封面文本和封底文本,请将“with ... Texts。”替换为:
其中不变部分列出了他们的标题, 前封面文本是列表,封面文本 是列表。
如果您没有封面文本的不变章节,或三者的其他组合,请合并这两种替代方案以适应这种情况。
如果您的文档包含程序代码的不寻常的示例,我们建议您在您选择的免费软件许可证(如GNU通用公共许可证)下并行发布这些示例,以允许其在自由软件中使用。
这是本手册中讨论的所有问题的一般索引,sed命令和命令行选项除外。
|
---|
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。