什么是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命令,他是这样写的:
bash
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文本编辑命令的语法是这样的:
bash
(匹配模式)(命令)(参数)
# 这里的括号实际不用写,只是便于理解罢了,
其中,我们就先以添加新行的sed文本编辑命令a
和i
为起点,并以下面的文本文件t.txt
作为示例,开始看sed文本编辑命令的实践吧。
bash
#!/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
bash
sed '1aecho start' t.txt

2. 往最后一行后面添加echo end
bash
sed '$aecho end' t.txt

3. 往第十一行后面添加# touch file
bash
sed '11a# touch file' t.txt

4. 往带字符c的行的后面添加# had char 'c' ^
bash
sed '/c/a# had char 'c' ^' t.txt

5. 往第一行前面插入# start
bash
sed '1i# start' t.txt

6. 往不带字符a-n的行前插入# no char 'a'-'n' v
bash
sed "/[a-n]/i"#" no char 'a'-'n' v" t.txt

7. 往行数不为1-10的行前插入# rows num >= 10
bash
sed '1,10!i # rows num >= 10' t.txt

8. 往行数为奇数的行前插入# odd num v
bash
sed '1~2i# odd num v' t.txt

删除行的sed文本编辑命令------d
1. 删除第十二行
bash
sed '12d' t.txt

2. 删除行数为偶数的行
bash
sed '2~2d' t.txt

3. 删除在每一个if和fi之间的行1
bash
sed '2,11d' t.txt

4. 删除在每一个if和fi之间的行2
bash
sed -r "/if|fi|then|\t/d" t.txt
# -r选项表示使用扩展正则库

5. 清空所有行
bash
sed 'd' t.txt
6. 删除第十二行到最后一行
bash
sed '12,$d' t.txt

修改行的sed文本编辑命令------c
, s
1. 将所有行修改为aaaaa
bash
sed 'caaaaa' t.txt

2. 将所有的echo命令改为echo echo
bash
sed '/echo/cecho echo' t.txt

3. 将所有带字符s或b的行改为***
bash
sed -e '/[sb]/c***' t.txt

4. 将所有带字符s或b的行改为***,并在第一行前面插入a,在最后一行后面添加b
bash
sed -e '/[sb]/c***' -e '$ab' t.txt | sed '1ia'

5. 将字符a转为b,将字符c转为d
bash
sed 's/a/b/;s/c/d/' t.txt

6. 在没有then的每一行的末尾添加分号1
bash
sed -r '/then/!s/$/;/' t.txt

7. 在没有then的每一行的末尾添加分号2
bash
sed -r '/then/!s/$/&;/' t.txt

8. 在每一行的开头添加#
bash
sed 's/^/#/' t.txt

9. 在每一行的开头添加\t
bash
sed 's/^/\t/' t.txt

10. 在每一行的开头删除\t
bash
sed 's/^\t//' t.txt

其它命令
1. 输出2-7行
bash
sed -n '2,7p' t.txt

2. 输出1-10行
bash
sed -n '1,10p' t.txt

3. 输出行号
bash
sed '=' t.txt

区块命令
1. 将所有行都变为空行
bash
sed 'g' t.txt

2. 双写t.txt文件
bash
sed 'H;$G' t.txt

3. 将带有$的行都变为空行
bash
sed '/\$/g' t.txt

4. 在每一行的后面都插入空行
bash
sed 'G' t.txt

5. 在每一行的前面都插入空行
bash
sed 'i-' t.txt | sed '/^-$/g'

6. 交换奇偶行,奇数行后面没有行不交换
bash
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命令------功能强大的文本处理工具
