天天看点

shell三剑客之SED使用一、SED介绍二、使用三、正则表达式

一、SED介绍

SED(Stream EDitor)是一个文本解析转换工具。它遵循简单的工作流:读取、执行、显示。

  • 读取:SED从输入流(文件,管道或者标准输入)中读取一行并且存储到模式空间(pattern buffer)的内部缓冲区
  • 执行:默认情况下,所有的SED命令都在模式空间中顺序执行;而且SED命令将会在所有的行上依次执行,除非指定了行的地址
  • 显示:发送修改后的内容到输出流。在发送数据之后,模式空间将会被清空

注意

  • 模式空间是一块缓冲区,在sed编辑器执行命令时会保存待检查的文本
  • 默认情况下,所有的sed命令都是在模式空间中执行,因此输入文件并不会发生改变
  • 还有另外一个缓冲区叫做保持空间(hold buffer),在处理模式空间中的某些行时,可以用保持空间来临时保存一些行。在每一个循环结束的时候,sed会移除模式空间中的内容,但是该缓冲区中的内容在所有的循环过程中是持久存储的。

示例

首先查看quote.txt文件内容:

shell三剑客之SED使用一、SED介绍二、使用三、正则表达式

执行

sed '' quote.txt

结果如下:

shell三剑客之SED使用一、SED介绍二、使用三、正则表达式

处理流程:sed命令先将文本中的一行内容存储到它的模式空间中,然后在缓冲区执行命令;此处没有提供sed命令,所以对该缓冲区没有要执行的操作;最后删除模式空间的内容,并打印该内容到标准输出。最后流程总结如下:

一行内容->模式空间->执行命令->删除模式空间内容->打印

二、使用

2.1 基础语法

sed -option 'command' file

2.1.1 命令说明

command 说明
d 删除 (delete)
s 单个字符替换 (substitute)
p 打印 (print)
w 写入 (write)命令
a 追加 (append)
c 行替换 (change)
i 插入 (insert)
l 显示隐藏字符
q 退出命令 (quit)
r 文件读取 (read)
e 执行外部命令
! 排除命令
  • d

    books.txt内容如下:

    shell三剑客之SED使用一、SED介绍二、使用三、正则表达式
    执行

    sed '2d' books.txt

    命令,删除第二行内容:
    shell三剑客之SED使用一、SED介绍二、使用三、正则表达式
  • s

    执行

    sed 's/$/!/'

    命令,给books.txt文件每一行结尾加上感叹号:
    shell三剑客之SED使用一、SED介绍二、使用三、正则表达式
  • p

    首先看

    sed 'p' quote.txt

    命令执行结果:
    shell三剑客之SED使用一、SED介绍二、使用三、正则表达式

    sed '' quote.txt

    命令相比,每一行打印了两次,这是因为在内容读取进模式空间进行处理的时候,执行的命令是

    p

    ,打印内容(第一次),在处理完毕之后,模式空间的内容又打印到标准输出(第二次)。

可以使用

-n

参数来抑制第二次的打印行为,

sed -n 'p' quote.txt

执行结果如下,同

sed '' quote.txt

命令结果相同:

shell三剑客之SED使用一、SED介绍二、使用三、正则表达式
  • w

    语法

[address] w file
file是要写入的文件名,如果文件名不存在,则会自动创建,如果已经存在,则会覆盖原内容
           

观察以下两条示例:

sed -n 'w books.bak' books.txt

,由于没有指定地址,那么会将文件books.txt的所有内容都写入到新文件中。

shell三剑客之SED使用一、SED介绍二、使用三、正则表达式

sed -n '2,3 w junk.txt' books.txt

,将2到3行内容写到新文件中

shell三剑客之SED使用一、SED介绍二、使用三、正则表达式
  • a

    sed '$a 7) my append txt' books.txt

    ,给最后一行追加内容
    shell三剑客之SED使用一、SED介绍二、使用三、正则表达式
  • c

    当提供行的地址范围时,所有行都被作为一组替换成单行文本

sed '2,3c they are changed' books.txt

命令,替换2,3行内容:

shell三剑客之SED使用一、SED介绍二、使用三、正则表达式
  • i

    sed '1i insert txt' books.txt

    ,给第一行插入内容,插入到前一行:
    shell三剑客之SED使用一、SED介绍二、使用三、正则表达式
  • l

    sed 's/ /\t/g' books.txt > junk.txt

    ,首先将books.txt中的空格替换成/t

    sed -n 'l' junk.txt

    ,查看junk.txt文件的隐藏字符
    shell三剑客之SED使用一、SED介绍二、使用三、正则表达式
    此外,

    l

    命令还能让文本按照指定的宽度换行:

    sed -n 'l 40' books.txt

    ,文本中的每一行如果超过40字符,则换行:
    shell三剑客之SED使用一、SED介绍二、使用三、正则表达式
  • q

    语法

[address]q [value]
只支持单个地址匹配
value作为程序的返回,可以写也可不写
           

sed '3q 6' books.txt

,匹配第三行退出,返回值6:

shell三剑客之SED使用一、SED介绍二、使用三、正则表达式
  • r

    r

    命令可以从外部文件中读取内容,并在满足条件的时候显示
[address]r file
           

sed '3r junk.txt' books.txt

,将junk.txt文件内容在第三行之后显示:

shell三剑客之SED使用一、SED介绍二、使用三、正则表达式
  • e

    sed '3e date' books.txt

    ,执行外部命令date:
    shell三剑客之SED使用一、SED介绍二、使用三、正则表达式
  • !

    使原来起作用的命令不起作用

    sed '/Paulo/!p' books.txt

    :
    shell三剑客之SED使用一、SED介绍二、使用三、正则表达式

2.1.2 参数说明

option 说明
-n 抑制输出
-e 执行多条命令
-f 执行指定脚本文件里的命令
  • -n

    默认情况下,模式空间的内容在处理完毕之后将会打印到标准输出,该选项用于阻止该行为。

可以查看

sed '' quote.txt

命令加-n参数和不加参数的情况如下

shell三剑客之SED使用一、SED介绍二、使用三、正则表达式
  • -e

使用-e选项,执行多次删除命令,

sed -e '2d;5d' books.txt

shell三剑客之SED使用一、SED介绍二、使用三、正则表达式
  • -f

脚本文件内容如下,即删除第二行和第五行内容:

shell三剑客之SED使用一、SED介绍二、使用三、正则表达式

执行

sed -f testCommand books.txt

命令,结果中删除了第二行和第五行内容,说明命令生效:

shell三剑客之SED使用一、SED介绍二、使用三、正则表达式

2.2 循环和分支

sed提供用于控制执行流的循环和分支语句

2.2.1 循环

sed可以根据标签(label)跳转到某一行继续执行;我们可以定义如下标签:

:label
:start
:end
:up
           

定义完标签之后,如果要跳转到指定的标签,使用b命令后跟着标签名;如果忽略标签名,sed将会跳转到sed文件的结尾。

b start    -->表示跳转到start标签的位置
           
  • 示例

    首先查看示例文件books2.txt的内容:

    shell三剑客之SED使用一、SED介绍二、使用三、正则表达式
    执行以下命令:
[email protected]:/opt/shell/sed-demo-master# sed -n '
> h;n;H;x
> s/\n/,/
> /Paulo/!b Print
> s/^/-/
> :Print
> p' books2.txt
           

结果:

shell三剑客之SED使用一、SED介绍二、使用三、正则表达式

命令分析:

  • 第一行

    h;n;H;x

    命令,

    h

    是指将当前模式空间中的内容覆盖到保持空间中;

    n

    是用于提前读取下一行,并覆盖当前模式空间中的这一行;

    H

    将当前模式空间的内容追加到保持空间;

    x

    用于交换模式空间和保持空间中的内容。最终达到的效果就是每次读取两行放到模式空间中进行处理。
  • 第二行

    s/\n/,/

    命令用于将上面的两行内容进行处理,把换行符替换成逗号。
  • 第三行

    /Paulo/!b Print

    命令,进行匹配,如果不满足匹配条件,则跳转到Print标签,否则执行第四行命令。
  • 第四行

    s/^/-/

    命令,将这一行的开头添加

    -

  • 第五行

    :Print

    只是一个标签名
  • 第六行

    p

    ,打印命令;

不符合匹配条件的执行流,过程为

2->3->5->6

;符合匹配条件的执行流,

2->3->4->5->6

,两者区别只是是否少了第四行命令而已,也就是说,标签后的内容,都是一样要执行的。

以上的命令也可以写在同一行:

sed -n 'h;n;H;x;s/\n/,/;/Paulo/!b Print;s/^/-/;:Print;s/^/!/;p' books2.txt
           
shell三剑客之SED使用一、SED介绍二、使用三、正则表达式

2.2.2 分支

使用t命令创建分支,只有当前置条件成功的时候,t命令才会跳转到该标签。

前置条件:替换(s)命令执行成功
  • 示例

    执行命令

sed -n '
> h;n;H;x
> s/\n/,/
> :loop
> /Paulo/s/^/-/
> /----/!t loop
> p' books2.txt

           

结果:

shell三剑客之SED使用一、SED介绍二、使用三、正则表达式

命令分析(前两行与以上示例一致):

  • 第三行

    :loop

    ,定义了一个loop标签
  • 第四行

    /Paulo/s/^/-/

    ,匹配存在Paulo的行,如果存在则在开头添加一个

    -

  • 第五行

    /----/!t loop

    (重点),检查上面添加

    -

    之后,是否满足有四个

    -

    ,如果不满足,则跳到第三行,继续往下执行,再向最前面添加一个

    -

    ;如果满足,则向下执行

    p

    命令。

所以此示例的前置条件就是第四行命令中的

s

命令执行成功,才会继续第五行命令。如果第四行命令没有执行成功,则直接执行最后一行

p

命令。

2.3 行寻址

sed中包含有以下两种形式的行寻址:

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

以上两中方式的语法都相同

[address]command
           

2.3.1 数字方式行寻址

  • 指定某一行,使用单独的数字

    sed -n '3d' books.txt

    ,指定第三行执行

    d

    命令
  • 指定行的范围,起始行和结束行之间用逗号隔开

    sed -n '2,5 p' books.txt

    ,第二行到第五行执行

    p

    命令
  • $代表文件最后一行
    shell三剑客之SED使用一、SED介绍二、使用三、正则表达式
  • M,+n

    ,选定第M行开始的下n行
    shell三剑客之SED使用一、SED介绍二、使用三、正则表达式
  • M~n

    ,选定M行开始的每n行
    shell三剑客之SED使用一、SED介绍二、使用三、正则表达式

2.3.2 文本模式过滤

  • /pattern/command

    ,使用/符号来开启匹配,同时以/符号结束
    shell三剑客之SED使用一、SED介绍二、使用三、正则表达式

2.4 多行命令

sed编辑器执行基础命令时,会基于换行符的位置将数据分成多行,一次处理一行的数据,然后移到下一行重复这个过程。

但是sed编辑器也有用来处理多行文本的特殊命令

命令 说明
N 将数据流中的下一行追加进来组成多行组一起处理
P 输出多行文本的模式空间中的第一行

2.4.1 N - 加载下一行

sed 'N;s/\n/,/' books2.txt

shell三剑客之SED使用一、SED介绍二、使用三、正则表达式

2.4.2 P - 输出第一行

sed -n 'N;P' books2.txt

shell三剑客之SED使用一、SED介绍二、使用三、正则表达式

2.5 特殊字符

sed中含有两个可以用作命令的特殊字符:= 和**&**

2.5.1

=

命令

用于输出行号

sed -n '$n' books2.txt

,输出最后一行的行号:

shell三剑客之SED使用一、SED介绍二、使用三、正则表达式

三、正则表达式

3.1 定位符

字符 说明
^ 匹配行的开头
$ 匹配行的结尾
  • ^

    sed '/^The/ p' books2.txt

    shell三剑客之SED使用一、SED介绍二、使用三、正则表达式
  • $
sed '/Coelho$/ p' books2.txt
           

3.2 特殊字符

字符 说明
. 匹配除了换行符以外的所有单个字符
  • .
$ echo -e 'cat\ndog\nmat\nrats' | sed -n '/..t$/ p' 
cat
mat
           

3.3 字符集相关

符号 说明
[] 匹配字符集
[^] 排除字符集
[-] 匹配字符范围
  • []
    shell三剑客之SED使用一、SED介绍二、使用三、正则表达式
  • [^]

    [^cn]

    ,排除出现c或者n字符
  • [-]

    [a-c]

    ,指出现a到c任一字符

3.4 限定符

字符 说明
匹配0次到1次
+ 匹配一次到多次
* 匹配0次到多次
{n} 精确匹配n次
{n,} 至少匹配n次
{n,m} 匹配n-m次

3.5 元字符

字符 说明
\s 匹配单个空白内容
\S 匹配单个非空白内容
\w 匹配单个单词
\W 匹配非单词

继续阅读