原理
sed一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区(pattern space)中的内容,处理完成后,把缓冲区(pattern space)的内容送往屏幕。接着清空缓冲区(pattern space),处理下一行,这样不断重复,直到文件末尾。
sed维护两个数据缓冲区:主动模式空间(pattern space)和辅助保留空间(hold space)。在“通常”操作中,SED从输入流读取一行存入pattern space,这里就是文本编辑操作发生的地方。hold space最初是空的,但也有在pattern space和hold space直接移动数据的命令。
1. s命令 替换命令
$ sed 's/oldstr/newstr/g' file.txt
用newstr替换匹配oldstr的字符串,g表示此行匹配全部替换。如果替换的字符串里有单引号,不能用 \’来转译,可以用双引号引用。
注意:此命令只是输出并不改变原文件,如果想改变原文件有两种方法:
重定向
$ sed 's/oldstr/newstr/g' file.txt > newfile.txt
$ rm file.txt
$ mv newfile.txt file.txt
或使用-i参数直接改变原文件
$ sed -i 's/oldstr/newstr/g' file.txt
sed还可以指定替换,如指定替换某行的内容,如下命令替换第3行,第2个匹配的内容:
$ sed -i '3s/oldstr/newstr/2' file.txt
如下命令替换4到10行,每行第3个及以后的匹配:
$ sed '4,10s/oldstr/newstr/3g'
多模式匹配
有时我们需要一次替换多个模式,可参看下面的示例(第一个模式把第一行到第三行的oldstr替换成newstr,第二个则把第3行以后的str1替换成了str2):
$ sed '1,3s/oldstr/newstr/g; 3,$s/str1/str2/g' my.txt
上面的命令同价于sed的-e参数:
$ sed -e '1,3s/oldstr/newstr/g' -e '3,$s/str1/str2/g' my.txt
我们还可以使用&来当做被匹配的变量,然后可以在其左右加一些东西,如给指定的字符串加中括号:
$ sed 's/str/[&]/g' my.txt
圆括号匹配
圆括号括起来的正则表达式所匹配的字符串会可以当成变量来使用,sed中使用的是\1,\2…(注意:圆括号需要转译\( reg \))
2. a命令和i命令
a就是append,i就是insert,它们是用来添加行的。
"在第一行之前插入字符串,2 a则表示在第2行后追加一行内容
sed '1 i insert-str' file.txt
还可以用匹配模式添加行:
" 在匹配到match-str后追加一行内容
sed '/match-str/a appedn-str' file.txt
3. c命令 替换匹配行
" 用replace-str替换第3行内容
sed '3 c replace-str' file.txt
4. d命令 删除匹配行
同上
5. p命令 打印命令
和grep类似,用-n参数(禁止自动输出pattern space内容)只输出匹配到的那行,否则会全部输出
sed -n '/match-str/p' file.txt
"多模式打印
sed -n '/matchstr1/,/matchstr2/p' file.txt
"从第3行开始打印到匹配成功
sed -n '3,/match-str/p' file.txt
6. pattern space和hold space
pattern space(模式空间)相当于车间sed把流内容在这里处理;
hold space(保留空间)相当于仓库,加工的半成品在这里临时储存(当然加工完的成品也在这里存储)。
操作pattern space和hold space的参数:
- d 删除pattern space的内容,开始下一个循环.
- h H 复制/追加pattern space的内容到hold space.
- g G 复制/追加hold space的内容到pattern space.
- x 交换hold space和pattern space的内容.
sed命令可以实现tac的功能
"反序一个文件的行:
$ sed '1!G;h;$!d' t.txt
其中的’1!G;h;$!d’可拆解为三个命令:
- 1!G —— 只有第一行不执行G命令,将hold space中的内容append回- 到pattern space
- h —— 第一行都执行h命令,将pattern space中的内容拷贝到hold space中
- $!d —— 除了最后一行不执行d命令,其它行都执行d命令,删除当前行
7. 其他知识点
- 数字前的+表示连续几行
- cmd可以多个,用分号分割,用大括号可以嵌套