sed是流编辑器(stream editor),可以用于处理文本文件,使用好sed可以处理很多事情,对shell编程也很有帮助
可以在linux操作系统中使用 man sed命令获取帮助信息
sed [-nefr] [操作]
选项与参数:
-n:使用安静模式,只有经过sed处理的行才会被列出来
-e:直接在命令行模式上进行sed编辑操作
-f:直接将sed的操作写在一个文件里,-f filename则可以执行filename里面的sed操作
-r:sed操作使用的是扩展型正则表达式的语法
-i:直接修改读取文件内容,而不是屏幕打印
操作说明:
[n1[,n2]] function
[n1[,n2]]代表要操作的行的范围,n1-n2范围(含n1,n2)
这里的范围比较灵活
5表示选择第五行
2,5表示选择2-5行,共4行
n~m表示选择从n行开始,步长为m的行
1~2选择奇数行(第一行开始,步长为2),同理,2~2表示偶数行
2,+3表示第二行和后面的三行,和2,5的效果一样
2,$表示第二行到最后一行
这里也可以选择正则匹配
/xxx/,+3选择出现xxx的行以及后面三行,如果后面三行中也出现了xxx,那么就会从这个xxx重新开始计数
/xxx/,/yyy/选择xxx到yyy之间的行,这里应该是先找到xxx,再找到下一个出现的yyy(如果找不到yyy,那就直到结尾)
function有下面这些内容
a:新增,a后面加字符,这些字符会在新的一行出现(选中行的下一行)
c:替换,c的后面加字符,替换选中的行
d:删除
i:插入,i的后面加字符,这些字符会在新的一行出现(选中行的上一行)
p:打印,将选择的数据打印出来,一般和-n选项一起使用
s:替换,可以搭配正则表达式使用
y:替换,y/abc/xyz/,一一映射,a替换成x,b替换成y,c替换成z
=:作用是输出匹配到的行的行号,例如 sed -n '/6/=' num.txt,输出文件num.txt中出现6的行号
n:作用是输出当前模式空间并清空模式空间,手动读取下一行,行号计数器自动更新到要读取的那一行
sed -n 'p;n' num.txt 输出奇数行(安静模式,先打印,接着一行读到模式空间,安静模式下不输出,以此类推,就只打印出奇数行)
sed -n 'n;p' num.txt 输出偶数行
N:读取下一行的内容追加到当前的模式空间尾部,追加时原有内容和新内容用换行符\n隔开,此时行号计数器的行号会更新为下一行的行号
D:删除模式空间第一个换行符\n之前的内容,然后进入下一轮的循环
P:输出模式空间第一个换行符\n之前的内容
h:将模式空间中的内容覆盖到保持空间,模式空间中的内容仍然保留
H:在保持空间尾部加上\n,并将模式空间的内容追加到保持空间的尾部,模式空间的内容仍然保留
g:将保持空间中的内容覆盖到模式空间
G:在模式空间尾部加上换行符\n,并将保持空间的内容追加到模式空间的尾部
x:交换模式空间和保持空间的内容
s替换命令
s/pattern/replacement/flags
pattern指的是要被替换的内容,replacement指的是要替换的新内容
flags的介绍如下:
n:1~512之间的数字,表示指定要替换的字符串第几次出现才进行替换
g:对所有匹配到的内容进行替换
p:打印和pattern匹配的行(替换后)
w file:将缓冲区的内容保存到指定的file文件中
replacement中的字符含义
&:代表pattern匹配的内容
\n:匹配第n个子串,该子串之前在pattern中用\(\)指定
举例:
sed -n 's/\(.*\)0\(.*\)/\1\2/p' num.txt 匹配行中带0的行,然后打印0前后的字符
sed -n 's/0/#&/p' num.txt 匹配带0的行,然后再前面加一个#
标签命令:
用于控制script循环中执行流的循环和分支语句,可以根据标签跳转到某一行命令继续执行
:label 通过这个格式去定义一个标签,不可放在地址表达式后面
blabel 无条件跳转到label标签上,如果省略label,则跳转到script尾部
tlabel 如果对最近读入的s(替换)命令能够执行成功,则跳转到label处
Tlabel 如果对最近读入的s(替换)命令不能执行成功,则跳转到label处
对模式空间中行的处理逻辑
1、读取输入流的第一行到模式空间中(此时行号计数器记录的行号为1)(移除读取到的行的尾随换行符)
2、当行被预设的模式匹配上时,则使用sed程序内部命令进行处理,不管内容是否匹配,都会默认自动输出模式空间中处理后的内容(尾随默认加上换行符)
3、清空模式空间中的内容
4、然后从输入流读取下一行到模式空间(行号计数器更新为下一行),并循环上面的操作,知道输入流所有的行都被处理完成
重复打印匹配的上一行
sed '/4/!{h;b};x;p;x' num.txt
在匹配行的上一行末尾添加内容
sed '/4/!{x;ba};x;s/$/test/;:a;${p;x}' num.txt
去除换行
sed ':a;N;s/\n//g;ta' num.txt
sed ':a;N;$!ba;s/\n//g' num.txt
sed ':a;N;s/\n//g;ba' num.txt