Linux之sed入门

1 sed 基本知识

sed编辑器的操作流程:

  1. 一次从输入中读取一行数据。
  2. 根据所提供的编辑器命令匹配数据。
  3. 按照命令修改流中的数据。
  4. 将新的数据输出到STDOUT。

sed命令的格式如下:

$ sed options script file

选项允许你修改sed命令的行为:

-e script    # 在处理输入时,将script中指定的命令添加到已有的命令中
-f file      # 在处理输入时,将file中指定的命令添加到已有的命令中
-n           # 不产生命令输出,使用print命令来完成输出
-i	         # 此选项会直接修改源文件,要慎用。
script       # 参数指定了应用于流数据上的单个命令。

需要用多个命令的两种方法:

  1. 使用 -e 选项在命令行中指定
$ cat file01.txt 
word01 word02 
$ sed -e 's/word01/w01/; s/word02/w02/'  file01.txt 
w01 w02
  1. 使用 -f 选项在单独的文件中指定
$ cat script01.sed 
s/word01/w01/
s/word02/w02/
$ sed -f script01.sed file01.txt 
w01 w02

2 sed 替换

2.1 sed 替换标记

有4种可用的替换标记:

数字      # 表明新文本将替换第几处模式匹配的地方
g        # 表明新文本将会替换所有匹配的文本;
p        # 会打印与替换命令中指定的模式匹配的行
w file   # 将替换的结果写到文件中。
$ cat file02.txt 
The line is first line
The line is second line
$ sed  's/line/row/' file02.txt
The row is first line
The row is second line
$ sed  's/line/row/2' file02.txt
The line is first row
The line is second row
$ sed  's/line/row/g' file02.txt
The row is first row
The row is second row
$ sed  -n 's/first/1st/p' file02.txt
The line is 1st line
$ sed  -n 's/first/1st/w test.txt' file02.txt
$ cat test.txt 
The line is 1st line

2.2 sed 替换字符

sed编辑器允许选择其他字符来作为替换命令中的字符串分隔符:

$ sed 's!/bin/bash!/bin/csh!' /etc/passwd

在这个例子中,感叹号被用作字符串分隔符。

2.3 sed 使用行寻址

默认情况下,在sed编辑器中使用的命令会作用于文本数据的所有行。
如果只想将命令作用于特定行或某些行,则必须用行寻址(line addressing)。
在sed编辑器中有两种形式的行寻址:

  1. 以数字形式表示行区间
  2. 用文本模式来过滤出行

两种形式都使用相同的格式来指定地址:

[address] command

也可以将特定地址的多个命令分组:

address {
command1
command2
command3
}

2.3.1 数字方式的行寻址

在命令中指定的地址可以是单个行号,或是用起始行号、逗号以及结尾行号指定的一定区间范围内的行

$ cat file03.txt 
The line is first line
The line is second line
The line is third line
The line is fourth line
$ sed  '2s/line/row/g' file03.txt
The line is first line
The row is second row
The line is third line
The line is fourth line
# 只修改地址指定的第二行的文本
$ sed  '1,3s/line/row/g' file03.txt
The row is first row
The row is second row
The row is third row
The line is fourth line
# 使用了行地址区间,从第1行到第3行
$ sed  '2,$s/line/row/g' file03.txt
The line is first line
The row is second row
The row is third row
The row is fourth row
# 从某行开始的所有行,可以用特殊地址——美元符

2.3.2 文本模式过滤的行寻址

sed编辑器允许指定文本模式来过滤出命令要作用的行。格式如下:

/pattern/command

必须用正斜线将要指定的pattern封起来。sed编辑器会将该命令作用到包含指定文本模式的行上。

$ sed '/third/s/line/row/g' file03.txt 
The line is first line
The line is second line
The row is third row
The line is fourth line

2.3.3 命令组合

如果需要在单行上执行多条命令,可以用花括号将多条命令组合在一起。

$ sed '{s/line/row/g; s/is/isis/g}' file03.txt 
The row isis first row
The row isis second row
The row isis third row
The row isis fourth row
# 或者
$ sed '{
> s/line/row/g
> s/is/isis/g
> }' file03.txt
The row isis first row
The row isis second row
The row isis third row
The row isis fourth row

3 sed 删除

删除命令 d 名副其实,它会删除匹配指定寻址模式的所有行

$ sed 'd' file03.txt 
$ sed '3d' file03.txt 
The line is first line
The line is second line
The line is fourth line
$ sed '1,3d' file03.txt 
The line is fourth line
$ sed '2,$d' file03.txt 
The line is first line
$ sed '/second/d' file03.txt 
The line is first line
The line is third line
The line is fourth line

使用两个文本模式来删除某个区间内的行。
你指定的第一个模式会“打开”行删除功能,第二个模式会“关闭”行删除功能。
sed编辑器会删除两个指定行之间的所有行(包括指定的行)。

$ cat file03.txt 
The line is first line
The line is second line
The line is third line
The line is fourth line
$ sed '/first/,/third/d' file03.txt 
The line is fourth line

除此之外,你要特别小心,因为只要sed编辑器在数据流中匹配到了开始模式,删除功能就会打开。这可能会导致意外的结果。

$ cat file04.txt 
The line is first line
The line is second line
The line is third line
The line is fourth line
The line is first line again
The line is second line again
$ sed '/first/,/third/d' file04.txt 
The line is fourth line

第二个出现“first”的行再次触发了删除命令,因为没有找到停止模式,所以就将数据流中的剩余行全部删除了。当然,如果你指定了一个从未在文本中出现的停止模式,显然会出现另外一个问题。

$ sed '/first/,/five/d' file04.txt 
$

因为删除功能在匹配到第一个模式的时候打开了,但一直没匹配到结束模式,所以整个数据流都被删掉了。

4 sed 插入和附加文本

  • 插入(insert)命令(i)会在指定行前增加一个新行;
  • 附加(append)命令(a)会在指定行后增加一个新行。

这两条命令的费解之处在于它们的格式。它们不能在单个命令行上使用。你必须指定是要将行插入还是附加到另一行。格式如下:

sed '[address]command\new line'

new line中的文本将会出现在sed编辑器输出中你指定的位置。
当使用插入命令时,文本会出现在数据流文本的前面。

$ cat file02.txt 
The line is first line
The line is second line
$ sed '1i\The line is test line' file02.txt 
The line is test line
The line is first line
The line is second line

当使用附加命令时,文本会出现在数据流文本的后面。

$ sed '1a\The line is test line' file02.txt 
The line is first line
The line is test line
The line is second line

要插入或附加多行文本,就必须对要插入或附加的新文本中的每一行使用反斜线,直到最后一行。

$ sed '1i\
> The line is test line\
> The line is another test line' file02.txt
The line is test line
The line is another test line
The line is first line
The line is second line
# 或者,单行需要使用换行符 \n
$ sed '1i\The line is test line\nThe line is another test line' file02.txt 
The line is test line
The line is another test line
The line is first line
The line is second line

5 sed 修改行

修改(change)命令允许修改数据流中整行文本的内容。它跟插入和附加命令的工作机制一样,你必须在sed命令中单独指定新行。

$ cat file03.txt 
The line is first line
The line is second line
The line is third line
The line is fourth line
# 修改第 2 行中的文本
$ sed '2c\The line is test line' file03.txt 
The line is first line
The line is test line
The line is third line
The line is fourth line
# 修改它匹配的数据流中的任意文本行
$ sed '/third/c\The line is test line' file03.txt 
The line is first line
The line is second line
The line is test line
The line is fourth line
# 在修改命令中使用地址区间,会用这一行文本来替换数据流中地址区间内的文本,而不是逐一修改每行文本。
$ sed '2,3c\The line is test line' file03.txt 
The line is first line
The line is test line
The line is fourth line

6 sed 转换命令

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

[address]y/inchars/outchars/

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

$ cat file03.txt 
The line is first line
The line is second line
The line is third line
The line is fourth line
$ sed 'y/le/12/' file03.txt 
Th2 1in2 is first 1in2
Th2 1in2 is s2cond 1in2
Th2 1in2 is third 1in2
Th2 1in2 is fourth 1in2

注意:转换命令是一个全局命令,你无法限定只转换在特定地方出现的字符。

7 sed 回顾打印

  • p命令用来打印文本行;
  • 等号(=)命令用来打印行号;
  • l(小写的L)命令用来列出行。

7.1 打印行

在命令行上用-n选项,你可以禁止输出其他行,只打印包含匹配文本模式的行。也可以用它来快速打印数据流中的某些行。

$ sed '/third/p' file03.txt 
The line is first line
The line is second line
The line is third line
The line is third line
The line is fourth line
$ sed -n  '/third/p' file03.txt 
The line is third line
$ sed -n  '2,3p' file03.txt 
The line is second line
The line is third line

需要在修改之前查看行,也可以使用打印命令,比如与替换或修改命令一起使用。可以创建一个脚本在修改行之前显示该行。

$ sed  -n '/third/p;s/third/3rd/p' file03.txt 
The line is third line
3. The line is 3rd line

sed编辑器命令会查找包含"third"的行,然后执行两条命令。首先,脚本用p命令来打印出原始行;然后它用s命令替换文本,并用p标记打印出替换结果。输出同时显示了原来的行文本和新的行文本。

7.2 打印行号

$ sed '=' file03.txt 
1
The line is first line
2
The line is second line
3
The line is third line
4
The line is fourth line

7.3 列出行

列出(list)命令(l)可以打印数据流中的文本和不可打印的ASCII字符。任何不可打印字符要么在其八进制值前加一个反斜线,要么使用标准C风格的命名法(用于常见的不可打印字符),比如\t,来代表制表符。

$ sed -n 'l' file02.txt 
The line is first line$
The line is second line$
$ sed  'l' file02.txt 
The line is first line$
The line is first line
The line is second line$
The line is second line

8 sed 处理文件

8.1 写入文件

w命令用来向文件写入行。该命令的格式如下:

[address]w filename

filename可以使用相对路径或绝对路径,但不管是哪种,运行sed编辑器的用户都必须有文件的写权限。地址可以是sed中支持的任意类型的寻址方式,例如单个行号、文本模式、行区间或文本模式。

$ sed '1,3w test.txt' file03.txt 
The line is first line
The line is second line
The line is third line
The line is fourth line
$ cat test.txt 
The line is first line
The line is second line
The line is third line

$ sed '/third/w test.txt' file03.txt 
The line is first line
The line is second line
The line is third line
The line is fourth line
$ cat test.txt 
The line is third line

8.2 读取文件

读取(read)命令(r)允许你将一个独立文件中的数据插入到数据流中
读取命令的格式如下:

[address]r filename

filename 参数指定了数据文件的绝对路径或相对路径。你在读取命令中使用地址区间,只能指定单独一个行号或文本模式地址。sed编辑器会将文件中的文本插入到指定地址后。

$ cat file02.txt 
The line is first line
The line is second line
$ cat file05.txt 
The line is test line
The line is another test line
$ sed '1r file05.txt' file02.txt
The line is first line
The line is test line
The line is another test line
The line is second line
$ sed '1,2r file05.txt' file02.txt
The line is first line
The line is test line
The line is another test line
The line is second line
The line is test line
The line is another test line
# 使用地址区间时,会在每行后都插入
$ sed '$r file05.txt' file02.txt
The line is first line
The line is second line
The line is test line
The line is another test line
$ sed '/first/r file05.txt' file02.txt
The line is first line
The line is test line
The line is another test line
The line is second line

sed中的r命令会把其后面的任何字符判读为文件名,直到回车符或是单引号,一般对r命令的写法有下面的几种:

# 第一种写法
$ sed '/pattern/{r file1
> other cmd
> }' file2 
$ # 第二种写法,这里使用-e,相当于第一种用法
$ sed -e '/pattern/{r file1' -e 'other cmd}' file2 

读取命令的另一个用法是和删除命令配合使用:利用另一个文件中的数据来替换文件中的占位文本

$ cat file05.txt 
The line is test line
The line is another test line
$ cat file06.txt 
The line is first line
The line is second line
NEW_LINE
$ sed -e '/NEW_LINE/{r file05.txt' -e 'd}'  file06.txt 
The line is first line
The line is second line
The line is test line
The line is another test line

你可能感兴趣的:(Linux)