标签: Linux sed 4.5版本 参考文档 帮助文档 全文翻译 随带20个示例 详细解析
版权声明:本文为博主原创译文,未经博主允许不得转载。https://blog.csdn.net/qq_39785418/article/details/89763921
文档记录了一个版本4.5的流编辑器——GNU sed。
版权所有© 1998—2018自由软件基金会。
根据GNU免费文档许可证、自由软件基金会发布1.3及其后续版本,本文档被允许复制、分发和、或修改;没有不变的章节,没有封面文本,也没有封底文本。许可证副本包含在标题为“GNU免费文档许可证”的部分中。
通过翻译该文档,让自己理解sed更深,但这也花费了我近2个月的时间,这主要是自己英语不够好、原来对sed掌握的仅仅是皮毛且以及中文组织能力弱等有关。该文档对sed描述的比较全面,当然有一部分命令也只有说明,没有相应的示例。
为了能更好地理解,译者在翻译过程中添加了不少注释;在理解原文含义后,有些地方语言组织采用了我以为更好的表达方式。也发现了一些错误。有些术语的表述不一定标准。有些知识点我从网上查询并翻译后加入。特别指出的是,第7章节的20个示例中的注释,原文不多,我基本上对脚本执行的命令和流程进行了详细的描述,对于理解每个命令应该会帮助的。
从理解和掌握sed命令角度来看,一定要使用sed的调试程序,例如sedsed,只有这样才能看到程序是如何一步步执行的。提醒一下,sedsed-1.0好像不支持扩展正则表达式;学习sed最好有一定的正则表达式基础;我的测试环境是CentOS 7.5。
其实自己是Linux新手,翻译会有不少错误,也有不少笔误,请指正,谢谢!
sed是一个流编辑器,用于处理来自文件或管道的输入流,进行基本文本的匹配及处理。虽然在某些方面类似于允许进行脚本编辑(例如ed)的编辑器,但是sed仅仅对其输入内容从头到尾逐行读入、匹配和处理,因此效率更高。sed能够对来自于管道的文本进行过滤,与其他类型编辑器相比,这是它的独特之处。
本章将介绍如何运行sed。下一章将详细讨论sed脚本和各个sed命令。
通常调用sed命令是这样的:
sed SCRIPT INPUTFILE . . .
(SCRIPT脚本,INPUTFILE输入文件)例如,如果输入文件input.txt中有包含 ‘hello’ 的行,s命令就会把这些行中出现的第一个‘hello’替换成‘world’:
sed ‘s/hello/world/’ input.txt > output.txt # > 是输出重定向
如果您没有指定输入文件,或者输入文件位置是‘-’,sed就会过滤从标准输入(键盘)输入的的内容。下列命令是等价的:
sed ‘s/hello/world/’ input.txt > output.txt
sed ‘s/hello/world/’ < input.txt > output.txt
cat input.txt | sed ‘s/hello/world/’ - > output.txt
sed默认把输出内容打印到标准输出(译者:屏幕)中。使用‘-i’(in-place)选项就会对原始输入文件进行就地编辑(译者:如果没有使用这个选项,sed命令处理不会影响原始输入文件),而不是输出到标准输出中。还请参阅‘W’和‘s///w’(译者:W或w是write缩写)命令,用以把输出写入到其他文件中。下面的命令修改file.txt文件本身,不会有任何屏幕输出:
sed -i ‘s/hello/world/’ file.txt
sed默认输出所有的输入,除了使用命令修改或删除输入内容外(例如使用d代表delete删除命令等)。使用‘–n’选项可以关闭默认自动输出,而此时只能使用‘p’(print打印)命令打印匹配的特殊行。下面的命令只打印输入文件的第45行内容:
sed -n ‘45p’ file.txt
sed将多个输入文件视为一个长的数据流。下面的示例打印第一个文件(one.txt)的第一行和最后一个文件(three.txt)的最后一行。可以使用‘-s’(译者:separate的缩写,即各个输入的文件相互独立)选项来反转此行为。
sed -n ‘1p; $p’ one.txt two.txt three.txt
如果没有使用‘–e’(译者:后面跟脚本)或‘–f’(译者:后面跟脚本文件)选项,sed就把第一个非选项参数作为脚本,并把后续的非选项参数都当成要处理的输入文件。如果使用‘–e’选项指定脚本,则把所有非选项参数作为输入文件。选项‘–e’和‘–f’可以组合使用,并且可以出现多次,最终有效的脚本将由所有单独脚本的连接而成。
下面的例子功能是等价的:
sed ‘s/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 OPTIONS . . . [SCRIPT] [INPUTFILE . . .]
(sed 选项 . . . [脚本] [输入文件 . . .])
sed可以使用以下命令行选项调用:
--version 打印正在运行的sed版本和版权通知,然后退出。
--help 打印一条如何使用sed的帮助,简要说明这些命令行选项和出现bug时的报告地址,然后退出。
-n
--quiet
--silent 默认情况下,sed会在每次脚本循环结束前打印模式空间内容 (参见第6.1节[sed如何工作])。
而这些选项禁用了自动打印,这种情况下,sed仅在使用‘p’命令显式告知打印时才输出。
-e script
--expression=script
在处理输入时,将脚本中的命令都添加到准备运行的命令集中。
-f script-file
--file=script-file
在处理输入时,把包含在脚本文件中的命令都添加到准备运行的命令集中。
-i[SUFFIX]
--in-place[=SUFFIX]
此选项指定对原文件进行就地编辑。GNU sed通过创建一个临时文件并把输出发送到此临时文件,而不发送到标准输出来
实现这一点。(备注:这也适用于‘=、a、c、i、l、p’等命令。您仍然可以使用‘w’或‘W’命令和‘/dev/stdout’特殊文件
写入到标准输出。)
该选项隐含指定选项‘-s’或‘--separate’。
到达输入文件结尾时,该临时文件将被重命名为输入文件的原始文件名。如果提供了扩展名后缀(SUFFIX),
在重命名临时文件之前,该扩展名用于修改原文件名,从而生成备份副本(译者:也就是说,原始的输入文件名修改成备份副本,
临时文件名重命名为原始的输入文件名)。(备注:请注意,GNU sed无论是否实际更改了任何输出,都会创建备份文件。)
遵循以下规则:如果扩展名不包含‘*’,则将其作为后缀(SUFFIX)附加到当前文件名的末尾;如果扩展名包含一个或
多个‘*’字符,则将每个‘*’都替换为当前文件名。这允许您向备份文件添加前缀,而不是(或添加)后缀,甚至可以将
原始文件的备份副本放入另一个目录(前提是该目录已经存在)。
如果没有提供扩展名(SUFFIX),则会覆盖原始文件而不进行备份(译者:这就是就地编辑内部机制!)。
由于‘-i’有一个可选的参数,所以在其后不能跟随其他短选项:
sed -Ei ‘ . . . ‘ FILE
这与没有备份后缀参数的选项‘-E -i’一样。文件(FILE)会被就地编辑,不会创建备份文件。
sed -iE ‘ . . . ‘ FILE
这与‘--in-place=E’长选项一样,创建一个文件名为FILE的备份文件 FILEE。
小心同时使用‘-n -i’:前者禁止了自动打印功能,后者在没有备份的情况下就地编辑了原文件。如果不小心使用了该混合
选项组合(且没有显式使用‘p’命令),输出文件(译者:即原文件)将为空:
# 错误用法:‘FILE’会清空。
sed -ni ‘s/foo/bar/’ FILE
-l N
--line-length=N
为‘l’选项指定默认的换行长度。如果这个N指定为0(零),则意味着不换行。如果没有指定,N取值为70。
--posix GNU sed有一些POSIX sed的扩展。为了简化编写可移植的脚本,此选项将禁用此手册文档中的所有扩展,
包括其他扩展的命令。大多数扩展的sed接受超出POSIX规定语法的sed规范,但其中一些实际上违反了标准
(如第10章[报告错误]中描述的 N命令的行为)。如果只想禁用后一种扩展,可以将POSIXLY_CORRECT变量设置为非空。
-b
-binary 此选项在每个平台上都可用,但仅在操作系统区分文本文件和二进制文件时有效。像MS-DOS、Windows、Cygwin操作系统
有这样的区别,这些系统的文本文件由回车符和换行符分隔的行组成,而sed不能识别结尾的CR(译者:即回车换行符)。
当指定此选项时,sed将以二进制模式打开输入文件,因此不要求进行这种特殊处理,并把行视为在换行处结束。
--follow-symlinks
此选项仅在支持符号链接的平台上可用,并且仅在指定了选项‘-i’时有效。在这种情况下,如果在命令行上指定的文件
是符号链接,那么sed将跟踪链接并编辑链接的最终目标文件。默认行为是断开符号链接,这样就不会修改链接目标文件。
-E
-r
--regexp-extended
(regexp是regular express的缩写)使用扩展正则表达式,而不是基础正则表达式。扩展的正则表达式就是shell中
egrep命令可接受的表达式;由于它们通常使用更少的‘\’,所以更简洁。历史上这是一个GNU的扩展,但是这个‘-E’扩展是
最近才加到POSIX标准中(http://austingroupbugs.net/view.php ?id=528),所以使用‘-E’是为了可移植性。
GNU sed已经接受‘-E’这个未记录的选项多年,而且*BSD sed们也已经接受‘-E’多年,但是脚本中使用‘-E’可能导致不能
移植到其他较老的系统。参见5.4节[扩展正则表达式]。
-s
--separate
默认情况下,sed会把命令行上指定的多个文件视为一个单独的连续的长流(译者:也就是合并所有文件成一个大文件)。
GNU sed扩展通过使用该选项,允许用户把它们视为各自单独的文件。因此,像 ‘/abc/, /def/’ 这样的地址范围匹配
不会跨越多个文件;行号与每个文件的开始相联系;‘$’引用每个文件的最后一行,并且,被R命令调用的文件会倒回到
每个文件的开始。
--sandbox
在沙盒模式下,‘e、w、r’(译者:分别代表执行shell命令、写到文件、从文件读取)命令会被拒绝,包含这些命令的
程序在没有运行前就会中止。沙盒模式确保sed操作的仅仅是命令行上指定的输入文件,也不能运行外部程序。
-u
--unbuffered
尽可能少地缓冲输入和输出。如果输入来自于像 ‘tail -f’,并且您希望尽早看到转换后的输出结果,特别有用。
-z
--null-data
-zero-terminated
把输入内容当成文本行的集合,每一行由零字节(ASCII ‘NUL’字符)结尾,而不是换行符结束。该选项与 ‘sort -z’
和‘find -print0’等命令一起使用,可以处理任意文件名。
如果在命令行上没有使用‘-e’、‘-f’、‘–expression’或者‘–file’选项,那么,命令行上第一个非选项参数被当成要执行的脚本。
如果在处理完上述内容后仍有任何命令行参数,这些参数都将被解释为要处理的输入文件名。文件名“-”表示标准输入流。如果未指定文件名,则将处理标准输入。
退出状态码为零,表示成功,非零值表示失败。GNU sed返回以下退出状态码:
0 成功完成。
1 无效的命令、无效的语法、无效的正则表达式或者在‘--posix’下执行了GNU sed扩展的命令。
2 命令行上指定的一个或者多个输入文件不能打开(例如,文件找不到,或者无权限读取,被拒绝)。程序会继续处理其他文件。
4 出现一个I/O错误,或运行时发生严重的操作错误,GNU sed立即中止程序。
另外,q 和 Q 命令可自定义的退出状态码,用于中止sed(这是GNU sed扩展):
$ echo | sed ‘Q42’ ; echo $?
42