Blog

列出命令(l)

Content #

列出命令可以打印数据流中的文本和不可打印字符。在显示不可打印字符的时候,要么在其八进制值前加一个反斜线,要么使用标准的C语言命名规范(用于常见的不可打印字符),比如\t用于代表制表符: $ cat data10.txt This line contains tabs. This line does contain tabs. $ $ sed -n ’l’ data10.txt This\tline\tcontains\ttabs.$ This line does contain tabs.$ $ 制表符所在的位置显示为\t。行尾的美元符号表示换行符。如果数据流包含转义字符,则列出命令会在必要时用八进制值显示: $ cat data11.txt This line contains an escape character. $ $ sed -n ’l’ data11.txt This line contains an escape character. \a$ $ data11.txt文本文件含有一个用于产生铃声的转义控制码。当用cat命令显示文本文件时,转义控制码不会显示出来,你只能听到声音(如果打开了音箱的话)。但利用列出命令,就能显示出所使用的转义控制码。

From #

Linux命令行与shell脚本编程大全

打印行号命令(=)

Content #

等号命令会打印文本行在数据流中的行号。行号由数据流中的换行符决定。数据流中每出现一个换行符,sed编辑器就会认为有一行文本结束了: $ cat data1.txt The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. $ $ sed ‘=’ data1.txt 1 The quick brown fox jumps over the lazy dog. 2 The quick brown fox jumps over the lazy dog. 3 The quick brown fox jumps over the lazy dog. 4 The quick brown fox jumps over the lazy dog. $ sed编辑器在实际文本行之前会先打印行号。如果要在数据流中查找特定文本,那么等号命令用起来非常方便: $ cat data7.txt This is line number 1. This is line number 2. This is the 3rd line. This is the 4th line. This is line number 1 again; we want to keep it. This is more text we want to keep. Last line in the file; we want to keep it. $ $ sed -n ‘/text/{ > = > p > }’ data7.txt 6 This is more text we want to keep. $ 利用-n选项,就能让sed编辑器只显示包含匹配文本模式的文本行的行号和内容。

...

打印命令(p)

Content #

打印出已有的数据文本。打印命令最常见的用法是打印包含匹配文本模式的行: $ cat data6.txt This is line number 1. This is line number 2. This is the 3rd line. This is the 4th line. $ $ sed -n ‘/3rd line/p’ data6.txt This is the 3rd line. $ 在命令行中用-n选项可以抑制其他行的输出,只打印包含匹配文本模式的行。也可以用它来快速打印数据流中的部分行: $ sed -n ‘2,3p’ data6.txt This is line number 2. This is the 3rd line. $ 如果需要在使用替换或修改命令做出改动之前查看相应的行,可以使用打印命令。来看下面的脚本: $ sed -n ‘/3/{ > p > s/line/test/p > }’ data6.txt This is the 3rd line. This is the 3rd test. $ sed编辑器命令会查找包含数字3的行,然后执行两条命令。首先,脚本用打印命令打印出原始行;然后用替换命令替换文本并通过p标志打印出替换结果。输出同时显示了原始的文本行和新的文本行。

...

转换命令(y)

Content #

转换(y)命令是唯一可以处理单个字符的sed编辑器命令。该命令格式如下所示:

[address]y/inchars/outchars/

转换命令会对inchars和outchars进行一对一的映射。inchars中的第一个字符会被转换为outchars中的第一个字符,inchars中的第二个字符会被转换成 outchars中的第二个字符。这个映射过程会一直持续到处理完指定字符。如果 inchars和outchars的长度不同,则sed编辑器会产生一条错误消息。

来看一个使用转换命令的简单例子: $ cat data9.txt This is line 1. This is line 2. This is line 3. This is line 4. This is line 5. This is line 1 again. This is line 3 again. This is the last file line. $ $ sed ‘y/123/789/’ data9.txt This is line 7. This is line 8. This is line 9. This is line 4. This is line 5. This is line 7 again. This is line 9 again. This is the last file line. $ 如你所见,inchars中的各个字符都会被替换成outchars中相同位置的字符。转换命令是一个全局命令,也就是说,它会对文本行中匹配到的所有指定字符进行转换,不考虑字符出现的位置: $ echo “Test #1 of try #1.” | sed ‘y/123/678/’ Test #6 of try #6. $ sed编辑器转换了在文本行中匹配到的字符1的两个实例。你无法对特定位置字符的转换进行限制。

...

修改行(c)

Content #

修改(c)命令允许修改数据流中整行文本的内容。它跟插入和附加命令的工作机制一样,必须在sed命令中单独指定一行: $ sed ‘2c\ > This is a changed line of text. > ’ data6.txt This is line number 1. This is a changed line of text. This is the 3rd line. This is the 4th line. $ 在这个例子中,sed编辑器会修改第三行中的文本。也可以用文本模式来寻址: $ sed ‘/3rd line/c\ > This is a changed line of text. > ’ data6.txt This is line number 1. This is line number 2. This is a changed line of text. This is the 4th line. $ 文本模式修改命令会修改所匹配到的任意文本行: $ cat data8.txt I have 2 Infinity Stones I need 4 more Infinity Stones I have 6 Infinity Stones! I need 4 Infinity Stones I have 6 Infinity Stones… I want 1 more Infinity Stone $ $ sed ‘/have 6 Infinity Stones/c\ > Snap! This is changed line of text. > ’ data8.txt I have 2 Infinity Stones I need 4 more Infinity Stones Snap! This is changed line of text. I need 4 Infinity Stones Snap! This is changed line of text. I want 1 more Infinity Stone $ 可以在修改命令中使用地址区间,但结果未必如愿: $ cat data6.txt This is line number 1. This is line number 2. This is the 3rd line. This is the 4th line. $ $ sed ‘2,3c\ > This is a changed line of text. > ’ data6.txt This is line number 1. This is a changed line of text. This is the 4th line. $ sed编辑器会用指定的一行文本替换数据流中的两行文本,而不是逐一修改。

...

插入和附加文本

Content #

·插入(insert)(i)命令会在指定行前增加一行。·附加(append)(a)命令会在指定行后增加一行。两者的费解之处在于格式。这两条命令不能在单个命令行中使用。必须指定是将·行插入还是附加到另一行,其格式如下: sed ‘[address]command\ new line’

new line中的文本会出现在你所指定的sed编辑器的输出位置。记住,当使用插入命令时,文本会出现在数据流文本之前: $ echo “Test Line 2” | sed ‘i\Test Line 1’ Test Line 1 Test Line 2 $ 当使用附加命令时,文本会出现在数据流文本之后: $ echo “Test Line 2” | sed ‘a\Test Line 1’ Test Line 2 Test Line 1 $

要向数据流内部插入或附加数据,必须用地址告诉sed编辑器希望数据出现在什么位置。用这些命令时只能指定一个行地址。使用行号或文本模式都行,但不能用行区间。这也说得通,因为只能将文本插入或附加到某一行而不是行区间的前面或后面。

下面的例子将一个新行插入数据流中第三行之前: $ cat data6.txt This is line number 1. This is line number 2. This is the 3rd line. This is the 4th line. $ $ sed ‘3i\ > This is an inserted line. > ’ data6.txt This is line number 1. This is line number 2. This is an inserted line. This is the 3rd line. This is the 4th line. $ 下面的例子将一个新行附加到数据流中第三行之后: $ sed ‘3a\ > This is an appended line. > ’ data6.txt This is line number 1. This is line number 2. This is the 3rd line. This is an appended line. This is the 4th line. $ 这个过程和插入命令一样,只不过是将新文本行放到指定行之后。如果你有一个多行数据流,想要将新行附加到数据流的末尾,那么只需用代表数据最后一行的美元符号即可: $ sed ‘$a\ > This line was added to the end of the file. > ’ data6.txt This is line number 1. This is line number 2. This is the 3rd line. This is the 4th line. This line was added to the end of the file. $ 同样的方法也适用于在数据流的起始位置增加一个新行。这只要在第一行之前插入新行就可以了。要插入或附加多行文本,必须在要插入或附加的每行新文本末尾使用反斜线(\): $ sed ‘1i\ > This is an inserted line.\ > This is another inserted line. > ’ data6.txt This is an inserted line. This is another inserted line. This is line number 1. This is line number 2. This is the 3rd line. This is the 4th line. $ 指定的两行都会被添加到数据流中。

...

命令组(sed)

Content #

如果需要在单行中执行多条命令,可以用花括号将其组合在一起,sed编辑器会执行匹配地址中列出的所有命令:

$ sed '2{
> s/fox/toad/
> s/dog/cat/
> }' data1.txt
The quick brown fox jumps over the lazy dog.
The quick brown toad jumps over the lazy cat.
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
$

这两条命令都会应用于该地址。当然,也可以在一组命令前指定行区间:

$ sed '3,${
> s/brown/green/
> s/fox/toad/
> s/lazy/sleeping/
> }' data1.txt
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
The quick green toad jumps over the sleeping dog.
The quick green toad jumps over the sleeping dog.

From #

Linux命令行与shell脚本编程大全

...

替换标志

Content #

替换标志在替换命令字符串之后设置。

s/pattern/replacement/flags

有4种可用的替换标志。·数字,指明新文本将替换行中的第几处匹配。·g,指明新文本将替换行中所有的匹配。·p,指明打印出替换后的行。·w file,将替换的结果写入文件。

第一种替换表示,你可以告诉sed编辑器用新文本替换第几处匹配文本: $ sed ’s/test/trial/2’ data4.txt This is a test of the trial script. This is the second test of the trial script. $ 将替换标志指定为2的结果就是,sed编辑器只替换每行中的第二处匹配文本。替换标志g(global)可以替换文本行中所有的匹配文本: $ sed ’s/test/trial/g’ data4.txt This is a trial of the trial script. This is the second trial of the trial script. $ 替换标志p会打印出包含替换命令中指定匹配模式的文本行。该标志通常和 sed的-n选项配合使用: $ cat data5.txt This is a test line. This is a different line. $ $ sed -n ’s/test/trial/p’ data5.txt This is a trial line. $ -n选项会抑制sed编辑器的输出,而替换标志p会输出替换后的行。将二者配合使用的结果就是只输出被替换命令修改过的行。

...

sub:sed

Content #

保留空间(hold space) 替换标志 命令组(sed) 插入和附加文本 修改行(c) a,i命令与c命令的区别 转换命令(y) 打印命令(p) 打印行号命令(=) 列出命令(l) 写入文件命令(w) 读取文件命令(r) 替换文件中的占位文本 单行next(n)命令 多行next(N)命令 多行删除命令(D) 多行打印命令(P) N,P,D模式 处理跨行匹配中的最后一行文本(!,N,$) 使用保留空间来反转文本文件的行 分支命令(b) 用分支命令删除所有的逗号 测试命令(t) 用测试命令删除所有的逗号 sed模式替换中的&符号 子模式反向替换 在大数中插入逗号 加倍行间距 对可能含有空行的文件加倍行间距 给文件中的行编号 创建滚动窗口(rolling window) 删除连续的空行 删除开头的空行 删除结尾的空行 删除.H1开头的行之下的空行 删除跨行的注释 打印出名字及头衔(employee实例)

BEGIN与END关键字

Content #

BEGIN关键字允许指定一段脚本,在处理数据之前执行。 END关键字允许指定一段脚本,gawk会在处理完数据后执行这段脚本。可以将各个部分放到一起,组成一个漂亮的小型脚本文件,用它从一个简单的数据文件中创建一份完整的报告:

$ cat script4.gawk
BEGIN {
print "The latest list of users and shells"
print "UserID  \t Shell"
print "------- \t -------"
FS=":"
}

{
print $1 "       \t "  $7
}

END {
print "This concludes the listing"
}
$

其中,BEGIN脚本用于为报告创建标题。另外还定义了一个殊变量FS。这是定义字段分隔符的另一种方法。这样就无须依靠脚本用户通过命令行选项定义字段分隔符了。

下面是这个gawk脚本的输出(有部分删节):

$ gawk -f script4.gawk /etc/passwd
The latest list of users and shells
UserID           Shell
--------         -------
root             /bin/bash
daemon           /usr/sbin/nologin
[...]
christine        /bin/bash
sshd             /usr/sbin/nologin
This concludes the listing
$

和预想的一样,BEGIN脚本创建了标题,主体脚本处理了特定数据文件(/etc/passwd)中的信息,END脚本生成了页脚。print命令中的\t负责生成美观的选项卡式输出(tabbed output)。

...