什么是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文本编辑命令a和i为起点,并以下面的文本文件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命令——功能强大的文本处理工具