细说Linux文本三鼎甲之状元-sed

sed全称是:Stream EDitor(字符流编辑器)。所谓行行出状元,sed非常擅长行处理,而且支持正则表达式。处理起文件来虎虎生风,适合大场面。无论多少行的文件信手拈来,做个状元洒洒水小意思。
主要处理逻辑:读取文本数据时,把当前处理的行存储在临时缓冲区中(pattern space-模式空间),接看用sed命令处理缓冲区中的内容,处理好后,把缓冲区的内容输出。文本中的每一行都会经过这道流程进行处理,直到结束。

语法

sed [-hnV][-e<script>][-f<script文件>][文本文件]

sed + 参数 + 处理 + 文件
或者管道方式: 输入|sed + 参数 + 处理 + 输出

常用参数说明

* -e <script>或--expression=<script> 以选项中指定的script来处理输入的文本文件。其实就是不在原文件修改而是处理好后输出控制台。
* -f <script文件>或--file=<script文件> 以选项中指定的script文件来处理输入的文本文件。指定处理逻辑的文件(文件内容都是处理逻辑)
* -h 或--help 显示帮助。
* -n 或--quiet或--silent 仅显示script处理后的结果。
* -V 或--version 显示版本信息。

常用编辑命令

* a 追加,向匹配行后面插入内容
* c 更改,更改匹配行的内容
* i 插入,向匹配行前插入内容
* d 删除,删除匹配的内容
* s 替换,替换掉匹配的内容
* p 打印,打印出匹配的内容,通常与-n参数同时使用
* =: 用来打印被匹配行的行号
* n: 读取下一行,遇到n时自动跳到下一行
* r,w: 读写编辑,r用为读入文件,w将匹配内容写入文件

常见示例

测试文件:testSed.txt
[test@t1 sedtest]$ cat testSed.txt 
1aaa
2bbb
3ccc
4aaa
5aaa
6bbb
* 在第二行后追加'ppp' -> ''中2为行号,a为参数追加,ppp为追加内容
[test@t1 sedtest]$ sed '2appp' testSed.txt     
1aaa
2bbb
ppp
3ccc
4ddd
5aaa
6bbb
* 在内容为aaa后追加ppp -> 只要匹配到aaa后面都会追加ppp
[test@t1 sedtest]$ sed '/aaa/appp' testSed.txt 
1aaa
ppp
2bbb
3ccc
4ddd
5aaa
ppp
6bbb
* 在第二行之前增加test
[test@t1 sedtest]$ sed '2itest' testSed.txt            
1aaa
test
2bbb
3ccc
4ddd
5aaa
6bbb
* 在最后一行增加test
[test@t1 sedtest]$ sed '$atest' testSed.txt 
1aaa
2bbb
3ccc
4ddd
5aaa
6bbb
test
* 文件第二行内容替换为test
[test@t1 sedtest]$ sed '2ctest' testSed.txt       
1aaa
test
3ccc
4ddd
5aaa
6bbb
* 删除第三行
[test@t1 sedtest]$ sed '3d' testSed.txt 
1aaa
2bbb
4ddd
5aaa
6bbb
* 从第一行开始,每隔2行删除一行、第一行也删除
[test@t1 sedtest]$ sed '1~2d' testSed.txt 
2bbb
4ddd
6bbb
* 删除1到3行
[test@t1 sedtest]$ sed '1,3d' testSed.txt 
4ddd
5aaa
6bbb
* 除了1到3行都删除
[test@t1 sedtest]$ sed '1,3!d' testSed.txt   
1aaa
2bbb
3ccc
* 删除匹配到aaa的行
[test@t1 sedtest]$ sed '/aaa/d' testSed.txt 
2bbb
3ccc
4ddd
6bbb
* 从匹配行开始全部删除
[test@t1 sedtest]$ sed '/ddd/,$d' testSed.txt    
1aaa
2bbb
3ccc
* 删除匹配行已经后面一行
[test@t1 sedtest]$ sed '/ddd/,+1d' testSed.txt  
1aaa
2bbb
3ccc
6bbb
* 删除空行  sed '/^$/d' testSed.txt 
* 删除1到3行有aaa的行
[test@t1 sedtest]$ sed '1,3{/aaa/d}' testSed.txt 
2bbb
3ccc
4ddd
5aaa
6bbb
* 将每行第一次出现b替换为t
[test@t1 sedtest]$ sed 's/b/t/' testSed.txt   
1aaa
2tbb
3ccc
4ddd
5aaa
6tbb
* 将匹配到的b都替换为t
[test@t1 sedtest]$ sed 's/b/t/g' testSed.txt 
1aaa
2ttt
3ccc
4ddd
5aaa
6ttt
* 将第二次出现的b替换为t
[test@t1 sedtest]$ sed 's/b/t/2' testSed.txt  
1aaa
2btb
3ccc
4ddd
5aaa
6btb
* 匹配内容b后,从该行匹配内容2开始替换为空
[test@t1 sedtest]$ sed '/b/s/2.*//g' testSed.txt 
1aaa

3ccc
4ddd
5aaa
6bbb

* 将每行中第一列为数字内容加上小括号
[test@t1 sedtest]$ sed 's/^[0-9]/(&)/' testSed.txt 
(1)aaa
(2)bbb
(3)ccc
(4)ddd
(5)aaa
(6)bbb
* 输出文件中的第二行
[test@t1 sedtest]$ sed -n '2p' testSed.txt 
2bbb
* 输出文件中第二行到第四行
[test@t1 sedtest]$ sed -n '2,4p' testSed.txt 
2bbb
3ccc
4ddd
* 输出匹配aaa的行
[test@t1 sedtest]$ sed -n '/aaa/p' testSed.txt 
1aaa
5aaa
* 查看文件一共有多少行,类似wc -l
[test@t1 sedtest]$ sed -n "$=" testSed.txt 
6
[test@t1 sedtest]$ wc -l testSed.txt 
6 testSed.txt

开发中sed使用

* 删除空白行 :sed -i "/^$/d"   $1 #将空白行删除
* CLASSPATH中添加jar包: 
export JARS=`find /opt/soft/lib/jars -name  '*.jar' | xargs | sed  "s/ /:/g"`
CLASSPATH=$CLASSPATH:$JARS
* 原文本中对匹配上的数据进行全部替换: sed -i 's/原字符串/新字符串/g' test.txt 
小捐怡情,大捐感激,点下广告也是极好的