OnWorks Linux 和 Windows 在线工作站

商标

工作站免费在线托管

<上一页 | 内容 | 下一页>

口渴

拼音作为的姓名 口渴 是短期的 流编辑器. 它对文本流(一组指定文件或标准输入)执行文本编辑。 口渴 是一个功能强大但有点复杂的程序(有整本关于它的书),所以我们不会在这里完整地介绍它。

一般来说,方式 口渴 它的工作原理是给它一个单一的编辑命令(在命令行上)或包含多个命令的脚本文件的名称,然后它在文本流中的每一行上执行这些命令。 这是一个非常简单的例子 口渴 实际上:


[我@linuxbox ~]$ 回声“前面” | sed 's/前/后/'

背部

[我@linuxbox ~]$ 回声“前面” | sed 's/前/后/'

背部


在此示例中,我们使用 echo 生成一个单字文本流并将其通过管道传输到 口渴. 口渴,依次执行指令 s/前/后/ 在流中的文本上并产生输出“返回”作为结果。 我们还可以将这个命令识别为类似于“替换”(搜索和替换)命令 vi.

命令在 口渴 以一个字母开头。 在上面的例子中,替换命令由字母表示 s 和后面是搜索和替换字符串,用斜杠字符分隔作为分隔符。 分隔符的选择是任意的。 按照惯例,斜线字符经常被使用,但是 口渴 将接受任何紧跟在命令之后的字符作为分隔符。 我们可以这样执行相同的命令:



[我@linuxbox ~]$ 回声“前面” | sed 's_front_back_'

背部

[我@linuxbox ~]$ 回声“前面” | sed 's_front_back_'

背部


通过在命令后立即使用下划线字符,它成为分隔符。 正如我们将看到的,设置分隔符的能力可用于使命令更具可读性。

大多数命令在 口渴 前面可能有一个 地址,它指定将编辑输入流的哪一行。 如果省略地址,则编辑命令为 car-


在输入流中的每一行都进行了尝试。 地址的最简单形式是行号。 我们可以在我们的例子中添加一个:



[我@linuxbox ~]$ 回声“前面” | sed '1s/前/后/'

背部

[我@linuxbox ~]$ 回声“前面” | sed '1s/前/后/'

背部


添加地址 1 到我们的命令导致我们的替换在我们的单行输入流的第一行执行。 如果我们指定另一个数字:



[我@linuxbox ~]$ 回声“前面” | sed '2s/前/后/'

[我@linuxbox ~]$ 回声“前面” | sed '2s/前/后/'


我们看到没有进行编辑,因为我们的输入流没有第 2 行。地址可以用多种方式表示。 以下是最常见的:

表 20-7:sed 地址符号


地址 说明

地址 说明

n 行号,其中 n 是一个正整数。


图片

$ 最后一行。


图片

/正则表达式/ 与 POSIX 基本正则表达式匹配的行。 请注意,正则表达式由斜杠字符分隔。 可选地,正则表达式可以由替代字符分隔,通过指定表达式 \表达式,在 Moku:Pro 上 c 是替代字符。


图片

地址1,地址2 一系列线路从 地址1 地址2, 包括的。 地址可以是上述任何单一地址形式。


图片

第一~匹配数字所代表的行 第一,然后每一行在 间隔。 例如,1~2 指的是每条奇数行,5~5 指的是第 XNUMX 行,之后每隔 XNUMX 行。


图片

地址1,+n 匹配 地址1 和以下 n 线。


图片

地址! 匹配所有行,除了 地址,可以是上述任何一种形式。


图片


我们将使用 发行版.txt 之前的文件


在这一章当中。 首先,一系列行号:


图片

[我@linuxbox ~]$ sed -n '1,5p' 发行版.txt

SUSE 10.2 12 年 07 月 2006 日

Fedora 10 11 年 25 月 2008 日

SUSE 11.0 06 年 19 月 2008 日

Ubuntu 8.04 04 年 24 月 2008 日

Fedora 8 11 年 08 月 2007 日


在这个例子中,我们打印一系列行,从第 1 行开始到第 5 行。为此,我们使用 p 命令,它只会导致打印匹配的行。 然而,为了使其有效,我们必须包括选项 -n (无自动打印选项)导致 口渴 默认情况下不打印每一行。

接下来,我们将尝试一个正则表达式:



[我@linuxbox ~]$

sed -n '/SUSE/p' 发行版.txt

苏斯 10.2

12/07/2006

苏斯 11.0

06/19/2008

苏斯 10.3

10/04/2007

苏斯 10.1

05/11/2006


通过包含斜线分隔的正则表达式 /苏塞/,我们能够以与以下相同的方式隔离包含它的行 grep的.

最后,我们将通过添加感叹号 (!) 到地址:


[我@linuxbox ~]$

sed -n '/SUSE/!p' distros.txt

Fedora 10

11/25/2008

Ubuntu的8.04

04/24/2008

Fedora 8

11/08/2007

Ubuntu的6.10

10/26/2006

Fedora 7

05/31/2007

Ubuntu的7.10

10/18/2007

Ubuntu的7.04

04/19/2007

Fedora 6

10/24/2006

Fedora 9

05/13/2008

Ubuntu的6.06

06/01/2006

Ubuntu的8.10

10/30/2008

Fedora 5

03/20/2006


在这里我们看到了预期的结果:文件中除了匹配的行之外的所有行


正则表达式。

到目前为止,我们已经看了两个 口渴 编辑命令, s p. 以下是更完整的基本编辑命令列表:


表 20-8:sed 基本编辑命令


命令说明

命令说明

= 输出当前行号。


图片

a 在当前行后追加文本。


图片

d 删除当前行。


图片

i 在当前行前插入文本。


图片

p 打印当前行。 默认情况下,sed 打印每一行,并且只编辑与文件中指定地址匹配的行。 可以通过指定 -n 选项来覆盖默认行为。


图片

q Exit 退出 口渴 无需处理更多行。 如果

-n 选项未指定,输出当前行。


图片

Q Exit 退出 口渴 无需处理更多行。


图片

s/正则表达式/替代/ 替换内容 替代 哪里

正则表达式 被发现。 替代 可能包括特殊字符 &,相当于匹配的文本 正则表达式。 此外, 替代 可能包括序列 \1 通过 \9,它们是对应的子表达式的内容 正则表达式. 有关更多信息,请参阅讨论 回参考 以下。 在尾随斜杠之后 替代,可以指定一个可选标志来修改 s 命令的行为。


图片

y/set1/set2 通过转换字符来执行音译 set1 到相应的字符 set2。 请注意,与 tr, 口渴 要求两个集合的长度相同。


图片


这个 s 命令是迄今为止最常用的编辑命令。 我们将通过对我们的 发行版.txt 文件。 我们之前讨论过日期字段如何在 发行版.txt 不是“计算机友好”的——


垫。 虽然日期格式为 MM/DD/YYYY,但如果格式为 YYYY-MM-DD 会更好(为了便于排序)。 手动对文件执行此更改既耗时又容易出错,但是 口渴,这一改变可以一步完成:


图片

[我@linuxbox ~]$ sed 's/\([0-9]\{2\}\)\/\([0-9]\{2\}\)\/\([0-9]\{4\}\

)$/\3-\1-\2/' 发行版.txt

SUSE 10.2 2006-12-07

费多拉 10 2008-11-25

SUSE 11.0 2008-06-19

Ubuntu 8.04 2008-04-24

费多拉 8 2007-11-08

SUSE 10.3 2007-10-04

Ubuntu 6.10 2006-10-26

费多拉 7 2007-05-31

Ubuntu 7.10 2007-10-18

Ubuntu 7.04 2007-04-19

SUSE 10.1 2006-05-11

费多拉 6 2006-10-24

费多拉 9 2008-05-13

Ubuntu 6.06 2006-06-01

Ubuntu 8.10 2008-10-30

费多拉 5 2006-03-20

哇! 现在这是一个难看的命令。 但它有效。 只需一步,我们就更改了文件中的日期格式。 这也是为什么正则表达式有时被开玩笑地称为“只写”媒体的一个完美例子。 我们可以写它们,但有时我们无法阅读它们。 在我们被这个命令吓得逃跑之前,让我们看看它是如何构建的。 首先,我们知道该命令将具有以下基本结构:



sed的/正则表达式/替代/' 发行版.txt

sed的/正则表达式/替代/' 发行版.txt


我们的下一步是找出一个可以隔离日期的正则表达式。 由于它是 MM/DD/YYYY 格式并出现在行尾,我们可以使用这样的表达式:



[0-9]{2}/[0-9]{2}/[0-9]{4}$

[0-9]{2}/[0-9]{2}/[0-9]{4}$


它匹配两位数字、一个斜线、两位数字、一个斜线、四位数字和行尾。 所以这照顾 正则表达式, 但是关于 替代? 为了解决这个问题,我们必须引入


一些使用 BRE 的应用程序中出现的新正则表达式功能。 这个功能叫做 回参考 并像这样工作:如果序列\n 出现在 替代品 协调 n 是一个从 1 到 9 的数字,该序列将引用前面正则表达式中相应的子表达式。 要创建子表达式,我们只需将它们括在括号中,如下所示:



([0-9]{2})/([0-9]{2})/([0-9]{4})$

([0-9]{2})/([0-9]{2})/([0-9]{4})$


我们现在有三个子表达式。 第一个包含月份,第二个包含月份中的第几天,第三个包含年份。 现在我们可以构造 替代 如下:



\3-\1-\2

\3-\1-\2


这给了我们年、破折号、月份、破折号和日。 现在,我们的命令如下所示:


sed 's/([0-9]{2})/([0-9]{2})/([0-9]{4})$/\3-\1-\2/' distros.txt

sed 's/([0-9]{2})/([0-9]{2})/([0-9]{4})$/\3-\1-\2/' distros.txt


我们还有两个问题。 首先是我们的正则表达式中额外的斜杠会混淆 口渴 当它试图解释 s 命令。 第二个是因为 口渴,默认情况下,只接受基本的正则表达式,我们正则表达式中的几个字符将被视为文字,而不是元字符。 我们可以通过自由应用反斜杠来逃避有问题的字符来解决这两个问题:



sed 's/\([0-9]\{2\}\)\/\([0-9]\{2\}\)\/\([0-9]\{4\}\)$/\3-\1-\2/' dis tros.txt

sed 's/\([0-9]\{2\}\)\/\([0-9]\{2\}\)\/\([0-9]\{4\}\)$/\3-\1-\2/' dis tros.txt


在那里,您拥有了!

的另一个特点 s command 是使用可跟随替换字符串的可选标志。 其中最重要的是 g 标志,指示 口渴 将搜索和替换全局应用于一行,而不仅仅是应用于第一个实例,这是默认的。 下面是一个例子:


[我@linuxbox ~]$ 回声“aaabbbccc” | sed 's/b/B/'

aaabbccc

[我@linuxbox ~]$ 回声“aaabbbccc” | sed 's/b/B/'

aaabbccc


我们看到替换已执行,但仅替换到字母“b”的第一个实例,而其余实例保持不变。 通过添加 g 标志,我们可以更改所有实例:



[我@linuxbox ~]$ 回声“aaabbbccc” | sed 's/b/B/g'

aaabbbbccc

[我@linuxbox ~]$ 回声“aaabbbccc” | sed 's/b/B/g'

aaabbbbccc


到目前为止,我们只给出了 口渴 通过命令行的单个命令。 还可以使用以下命令在脚本文件中构造更复杂的命令 -f 选项。 为了演示,我们将使用 口渴 的配套 发行版.txt 文件以生成报告。 我们的报告将在顶部显示一个标题、我们的修改日期以及所有转换为大写的发行版名称。 为此,我们需要编写一个脚本,因此我们将启动我们的文本编辑器并输入以下内容:



# sed 脚本生成 Linux 发行版报告


1我\

\

Linux 发行版报告\


s/\([0-9]\{2\}\)\/\([0-9]\{2\}\)\/\([0-9]\{4\}\)$/\3-\1-\2/ y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/

# sed 脚本生成 Linux 发行版报告


1我\

\

Linux 发行版报告\


s/\([0-9]\{2\}\)\/\([0-9]\{2\}\)\/\([0-9]\{4\}\)$/\3-\1-\2/ y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/


我们将保存我们的 口渴 脚本为 已发行 并像这样运行它:


图片

[我@linuxbox ~]$ sed -f 发行版.sed 发行版.txt


Linux 发行版报告


SUSE

10.2

2006-12-07

FEDORA

10

2008-11-25

SUSE

11.0

2008-06-19

UBUNTU

8.04

2008-04-24

FEDORA

8

2007-11-08

SUSE

10.3

2007-10-04

UBUNTU

6.10

2006-10-26

FEDORA

7

2007-05-31

UBUNTU

7.10

2007-10-18


UBUNTU

7.04

2007-04-19

SUSE

10.1

2006-05-11

FEDORA

6

2006-10-24

FEDORA

9

2008-05-13

UBUNTU

6.06

2006-06-01

UBUNTU

8.10

2008-10-30

FEDORA

5

2006-03-20


# sed 脚本生成 Linux 发行版报告

# sed 脚本生成 Linux 发行版报告

正如我们所见,我们的脚本产生了想要的结果,但它是如何做到的呢? 让我们再看看我们的脚本。 我们会用 给行编号:



[我@linuxbox ~]$ cat -n 发行版

[我@linuxbox ~]$ cat -n 发行版


1

2

3

4

5

6

7

8

1

2

3

4

5

6

7

8


图片

1我\

\

Linux 发行版报告\


s/\([0-9]\{2\}\)\/\([0-9]\{2\}\)\/\([0-9]\{4\}\)$/\3-\1-\2/ y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/

1我\

\

Linux 发行版报告\


s/\([0-9]\{2\}\)\/\([0-9]\{2\}\)\/\([0-9]\{4\}\)$/\3-\1-\2/ y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/

我们脚本的第一行是 评论. 与 Linux 系统上的许多配置文件和编程语言一样,注释以 # 字符,然后是人类可读的文本。 注释可以放置在脚本中的任何位置(尽管不在命令本身内),并且对可能需要识别和/或维护脚本的任何人都有帮助。

第 2 行是一个空行。 像注释一样,可以添加空行以提高可读性。

更多来自Google的 口渴 命令支持行地址。 这些用于指定要对输入的哪些行进行操作。 行地址可以表示为单行号、行号范围以及表示输入的最后一行的特殊行号“$”。

第 3 行到第 6 行包含要插入地址 1(输入的第一行)的文本。 这 i 命令后跟反斜杠-回车序列以产生转义的回车,或称为 换行符. 这个序列可以在许多情况下使用,包括 shell 脚本,允许将回车嵌入到文本流中,而无需向解释器发出信号(在这种情况下 口渴) 表示已到达行尾。 这 i,同样地, a (附加文本,而不是插入它)和 c (替换文本)命令,允许多行文本,只要每一行(最后一行除外)都以换行符结尾。 我们脚本的第六行实际上是我们插入的文本的结尾,并以一个普通的回车而不是一个行继续符结尾,标志着 i 命令。


图片

注意:换行符由反斜杠后跟 立即

通过回车。 不允许有中间空间。


图片

第 7 行是我们的搜索和替换命令。 由于它前面没有地址,因此输入流中的每一行都受其操作的影响。

图片

第 8 行执行小写字母到大写字母的音译。 注意,不像 try 命令输入 口渴 不支持字符范围(例如, [a-z]),也不支持 POSIX 字符类。 再次,由于 y 命令前面没有地址,它适用于输入流中的每一行。


喜欢sed的人也喜欢...

sed 是一个非常强大的程序,能够对文本流执行相当复杂的编辑任务。 它最常用于简单的单行任务而不是长脚本。 许多用户更喜欢使用其他工具来完成更大的任务。 其中最流行的是 awk 和 perl。 这些不仅仅是像这里介绍的程序这样的工具,而是扩展到完整的编程语言领域。 perl,尤其是在许多系统管理和管理任务中经常被用来代替 shell 脚本,并且是一种非常流行的 Web 开发媒介。 awk 更专业一点。 它的特殊优势在于它能够处理表格数据。 它类似于 sed,因为 awk 程序通常逐行处理文本文件,使用类似于 sed 概念的地址后跟操作的方案。 虽然 awk 和 perl 都超出了本书的范围,但对于 Linux 命令行用户来说,它们是非常好的学习技能。


OnWorks 的顶级操作系统云计算: