shell三剑客之SED使用

一、SED介绍

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

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

注意

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

示例

首先查看quote.txt文件内容:
在这里插入图片描述
执行sed '' quote.txt结果如下:
在这里插入图片描述
处理流程: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使用_第1张图片
    执行sed '2d' books.txt命令,删除第二行内容:
    shell三剑客之SED使用_第2张图片

  • s
    执行sed 's/$/!/'命令,给books.txt文件每一行结尾加上感叹号:
    shell三剑客之SED使用_第3张图片

  • p
    首先看sed 'p' quote.txt命令执行结果:
    在这里插入图片描述
    sed '' quote.txt命令相比,每一行打印了两次,这是因为在内容读取进模式空间进行处理的时候,执行的命令是p,打印内容(第一次),在处理完毕之后,模式空间的内容又打印到标准输出(第二次)。

可以使用-n参数来抑制第二次的打印行为,sed -n 'p' quote.txt执行结果如下,同sed '' quote.txt命令结果相同:
在这里插入图片描述

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

观察以下两条示例:
sed -n 'w books.bak' books.txt,由于没有指定地址,那么会将文件books.txt的所有内容都写入到新文件中。
在这里插入图片描述

sed -n '2,3 w junk.txt' books.txt,将2到3行内容写到新文件中
在这里插入图片描述

  • a
    sed '$a 7) my append txt' books.txt,给最后一行追加内容
    shell三剑客之SED使用_第4张图片
  • c
    当提供行的地址范围时,所有行都被作为一组替换成单行文本

sed '2,3c they are changed' books.txt命令,替换2,3行内容:
在这里插入图片描述

  • i
    sed '1i insert txt' books.txt,给第一行插入内容,插入到前一行:
    shell三剑客之SED使用_第5张图片
  • l
    sed 's/ /\t/g' books.txt > junk.txt,首先将books.txt中的空格替换成/t
    sed -n 'l' junk.txt,查看junk.txt文件的隐藏字符
    shell三剑客之SED使用_第6张图片
    此外,l命令还能让文本按照指定的宽度换行:
    sed -n 'l 40' books.txt,文本中的每一行如果超过40字符,则换行:
    shell三剑客之SED使用_第7张图片
  • q
    语法
[address]q [value]
只支持单个地址匹配
value作为程序的返回,可以写也可不写

sed '3q 6' books.txt,匹配第三行退出,返回值6:
在这里插入图片描述

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

sed '3r junk.txt' books.txt,将junk.txt文件内容在第三行之后显示:
shell三剑客之SED使用_第8张图片

  • e
    sed '3e date' books.txt,执行外部命令date:
    shell三剑客之SED使用_第9张图片
  • !
    使原来起作用的命令不起作用
    sed '/Paulo/!p' books.txt:
    在这里插入图片描述

2.1.2 参数说明

option 说明
-n 抑制输出
-e 执行多条命令
-f 执行指定脚本文件里的命令
  • -n
    默认情况下,模式空间的内容在处理完毕之后将会打印到标准输出,该选项用于阻止该行为。

可以查看sed '' quote.txt命令加-n参数和不加参数的情况如下
在这里插入图片描述

  • -e

使用-e选项,执行多次删除命令,sed -e '2d;5d' books.txt
在这里插入图片描述

  • -f

脚本文件内容如下,即删除第二行和第五行内容:
在这里插入图片描述
执行sed -f testCommand books.txt命令,结果中删除了第二行和第五行内容,说明命令生效:
在这里插入图片描述

2.2 循环和分支

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

2.2.1 循环

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

:label
:start
:end
:up

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

b start    -->表示跳转到start标签的位置
  • 示例
    首先查看示例文件books2.txt的内容:
    shell三剑客之SED使用_第10张图片
    执行以下命令:
root@iZwz98umwfu68refxh45n0Z:/opt/shell/sed-demo-master# sed -n '
> h;n;H;x
> s/\n/,/
> /Paulo/!b Print
> s/^/-/
> :Print
> p' books2.txt

结果:
shell三剑客之SED使用_第11张图片

命令分析:

  • 第一行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

在这里插入图片描述

2.2.2 分支

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

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

  • 示例
    执行命令
 sed -n '
> h;n;H;x
> s/\n/,/
> :loop
> /Paulo/s/^/-/
> /----/!t loop
> p' books2.txt

结果:
shell三剑客之SED使用_第12张图片
命令分析(前两行与以上示例一致):

  • 第三行: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命令
  • $代表文件最后一行
    在这里插入图片描述
  • M,+n,选定第M行开始的下n行
    在这里插入图片描述
  • M~n,选定M行开始的每n行
    在这里插入图片描述

2.3.2 文本模式过滤

  • /pattern/command,使用/符号来开启匹配,同时以/符号结束
    在这里插入图片描述

2.4 多行命令

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

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

2.4.1 N - 加载下一行

sed 'N;s/\n/,/' books2.txt
shell三剑客之SED使用_第13张图片

2.4.2 P - 输出第一行

sed -n 'N;P' books2.txt
shell三剑客之SED使用_第14张图片

2.5 特殊字符

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

2.5.1 =命令

用于输出行号
sed -n '$n' books2.txt,输出最后一行的行号:
在这里插入图片描述

三、正则表达式

3.1 定位符

字符 说明
^ 匹配行的开头
$ 匹配行的结尾
  • ^
    sed '/^The/ p' books2.txt
    在这里插入图片描述
  • $
sed '/Coelho$/ p' books2.txt

3.2 特殊字符

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

3.3 字符集相关

符号 说明
[] 匹配字符集
[^] 排除字符集
[-] 匹配字符范围
  • []
    在这里插入图片描述
  • [^]
    [^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 匹配非单词

你可能感兴趣的:(shell,linux,shell)