sed命令——容易上手而又方便实用的文本编辑命令

213 阅读4分钟

什么是sed命令

sed命令,是一个功能非常强大的文本编辑命令,也是一个流编辑器,虽然它是非交互式的编辑器,但通过它自带的文本编辑命令,可以轻松方便的去编辑文本。

sed命令的执行流程

sed命令,首先它把要读取文件的每一行数据读取到缓存区中,然后,如果没有-n选项,就在匹配模式前输出文件中读取到的每一行数据,之后与读取到的数据跟sed文本编辑命令前的匹配模式进行匹配,如果匹配成功,就执行sed文本编辑命令,否则原样输出,之后继续读取文件下一行,直到文件全部读完为止。用流程图表示就是这样:

flowchart 
subgraph 文件
text\ntxet\naaaa
end
文件-->|读取每一行数据到缓存区|a{如果没有-n选项}-->|是|b[/输出文件每一行数据/]-->c{如果读取到的数据与sed命令前的匹配模式匹配成功}-->|是|执行sed文本编辑命令-->d["读取下一行,读完文件就结束"]-->|读取|文件
a-->|否|c-->|否|原样输出-->d

怎样写sed命令

sed命令,他是这样写的:

sed [选项] (模式匹配/sed的文本编辑命令) 文件...

其中,省略号表示前面的东西可以有多个,而sed的文本编辑命令这里先不谈。

sed的文本编辑命令的语法

要想熟练地运用sed,最要学会的就是先要掌握它的文本编辑命令及语法,把它学会了,你离sed命令的熟练运用也就不远了。在sed的文本编辑命令中,基础命令有以下几个:

命令用途方便记住的技巧说明
a在行后添加命令后面的字符串a = append
c改变行的内容c = change
d删除行d = delete
i在行前添加命令后面的字符串i = insert
n跳到下一行n = \n
p输出读取到的行p = print
s把需要匹配的字符串交换成需要交换的字符串s = swap并且s命令有两个参数,用/分隔,且第一个参数的前面和第二个后面都有/
=输出行数

除此之外,还有一些特殊的操作符。

特殊操作符用途方便记住的技巧
!匹配条件取反,写在匹配模式的后面! = 编程语言中的!
;分割多个命令; = 编程语言中的;
{}将多个命令合为一组,前面可以有匹配模式{} = 编程语言中的代码块 -> 命令块

而在这之后,就要先认识一下sed命令的还有一个我没介绍过的区,就是临时区,临时区,顾名思义就是临时的区,默认只有一个\n,通过刚才介绍过的缓存区和临时区,用户可以更加轻松方便的使用sed命令编辑文本。

那么,我们该如何操控sed命令的缓存区和临时区呢?就要学到下面的区块命令了。

命令用途
g临时区的内容重写缓存区的内容
G临时区的内容追加缓存区的内容
h缓存区的内容重写临时区的内容
H缓存区的内容追加临时区的内容
x交换两个区的内容

命令学到了,就要继续学一下sed文本编辑命令的语法了,sed文本编辑命令的语法是这样的:

(匹配模式)(命令)(参数)
# 这里的括号实际不用写,只是便于理解罢了,

其中,我们就先以添加新行的sed文本编辑命令ai为起点,并以下面的文本文件t.txt作为示例,开始看sed文本编辑命令的实践吧。

#!/bin/bash
if [ -e $1 ]
then
        echo had
        exit
fi
if [ 0 == $# ]
then
        echo error
        exit 1
fi
touch $1
chmod +x $1
echo "#!/bin/bash" > $1
vim $1

添加新行的sed文本编辑命令——a, i

1. 往第一行后面添加echo start

sed '1aecho start' t.txt

2. 往最后一行后面添加echo end

sed '$aecho end' t.txt

3. 往第十一行后面添加# touch file

sed '11a# touch file' t.txt

4. 往带字符c的行的后面添加# had char 'c' ^

sed '/c/a# had char 'c' ^' t.txt

5. 往第一行前面插入# start

sed '1i# start' t.txt

6. 往不带字符a-n的行前插入# no char 'a'-'n' v

sed "/[a-n]/i"#" no char 'a'-'n' v" t.txt

7. 往行数不为1-10的行前插入# rows num >= 10

sed '1,10!i # rows num >= 10' t.txt

8. 往行数为奇数的行前插入# odd num v

sed '1~2i# odd num v' t.txt

删除行的sed文本编辑命令——d

1. 删除第十二行

sed '12d' t.txt

2. 删除行数为偶数的行

sed '2~2d' t.txt

3. 删除在每一个if和fi之间的行1

sed '2,11d' t.txt

4. 删除在每一个if和fi之间的行2

sed -r "/if|fi|then|\t/d" t.txt
# -r选项表示使用扩展正则库

5. 清空所有行

sed 'd' t.txt

6. 删除第十二行到最后一行

sed '12,$d' t.txt

修改行的sed文本编辑命令——c, s

1. 将所有行修改为aaaaa

sed 'caaaaa' t.txt

2. 将所有的echo命令改为echo echo

sed '/echo/cecho echo' t.txt

3. 将所有带字符s或b的行改为***

sed -e '/[sb]/c***' t.txt

4. 将所有带字符s或b的行改为***,并在第一行前面插入a,在最后一行后面添加b

sed -e '/[sb]/c***' -e '$ab' t.txt | sed '1ia'

5. 将字符a转为b,将字符c转为d

sed 's/a/b/;s/c/d/' t.txt

6. 在没有then的每一行的末尾添加分号1

sed -r '/then/!s/$/;/' t.txt

7. 在没有then的每一行的末尾添加分号2

sed -r '/then/!s/$/&;/' t.txt

8. 在每一行的开头添加#

sed 's/^/#/' t.txt

9. 在每一行的开头添加\t

sed 's/^/\t/' t.txt

10. 在每一行的开头删除\t

sed 's/^\t//' t.txt

其它命令

1. 输出2-7行

sed -n '2,7p' t.txt

2. 输出1-10行

sed -n '1,10p' t.txt

3. 输出行号

sed '=' t.txt

区块命令

1. 将所有行都变为空行

sed 'g' t.txt

2. 双写t.txt文件

sed 'H;$G' t.txt

3. 将带有$的行都变为空行

sed '/\$/g' t.txt

4. 在每一行的后面都插入空行

sed 'G' t.txt

5. 在每一行的前面都插入空行

sed 'i-' t.txt | sed '/^-$/g'

6. 交换奇偶行,奇数行后面没有行不交换

sed -n '1~2h;2~2{G;p};$p' t.txt

sed命令的选项

选项用途记巧
-n不输出默认输出-n = not print
-r使用扩展正则表达式-r = regex
-e从左到右依次执行在每个-e后面的命令(执行多个命令)
-i直接修改文件

其中,由于这几个sed命令的选项对我们来说已经能解决90%的问题了,并且记起来也了如指掌,几乎不需要深度学习,所以我们的sed命令就先讲到这里了。

下篇预告

awk命令——功能强大的文本处理工具