shell文本过滤编程(九):sed命令

【版权声明:转载请保留出处:blog.csdn.net/gentleliu。Mail:shallnew at 163 dot com】
sed和awk类似,是很重要的文本过滤工具。
调用sed和调用awk一样,有三种方式:
1. 在命令行键入命令;
2.将sed命令插入脚本文件,然后调用sed;
3. 将sed命令插入脚本文件,并使sed脚本可执行。
使用sed命令行格式为:                
sed [option] ‘sed cmd’ inputfile
使用sed脚本文件,格式为:
sed [option] -f sed_script_file.sed inputfile

无论何种方式,如果sed没有指定输入文件,sed从标准输入中接受输入,一般是键盘或重定向结果。使用sed无论命令是什么,sed并不与初始化文件打交道,它操作的只是一个拷贝,然后所有的改动如果没有重定向到一个文件,将输出到屏幕。
sed选项如下:
-e进行多项编辑,即对输入行应用多条sed命令时使用
-n取消默认的输出
-f指定sed脚本的文件名
=============================================================
Sed有如下命令:
p 打印匹配行
= 显示文件行号
a \ 在定位行号后附加新文本信息
i \ 在定位行号后插入新文本信息
d 删除定位行
c \ 用新文本替换定位文本
s 使用替换模式替换相应模式
r 从另一个文件中读文本
w 写文本到一个文件
q 第一个模式匹配完成后推出或立即推出
l 显示与八进制 A S C I I代码等价的控制字符
{ } 在定位行执行的命令组
n 从另一个文件中读文本下一行,并附加在下一行
g 将模式2粘贴到/pattern n/
y 传送字符
n 延续到下一输入行;允许跨行的模式匹配语句
下面来讲一下sed的各种命令。本系列关于sed的示例使用以下文本文件:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #cat passwd  
  2. root:x:0:0:root:/root:/bin/sh  
  3. proxy:x:13:13:proxy:/bin:/bin/sh  
  4. operator:x:37:37:Operator:/var:/bin/sh  
  5. ftp:x:83:83:ftp:/home/ftp:/bin/sh  
  6. nobody:x:99:99:nobody:/home:/bin/sh  
  7. sshd:x:103:99:Operator:/var:/bin/sh  
  8. #  
1.    p命令
1)    使用P命令打印文件内容。
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #sed 'p' passwd  
  2. root:x:0:0:root:/root:/bin/sh  
  3. root:x:0:0:root:/root:/bin/sh  
  4. proxy:x:13:13:proxy:/bin:/bin/sh  
  5. proxy:x:13:13:proxy:/bin:/bin/sh  
  6. operator:x:37:37:Operator:/var:/bin/sh  
  7. operator:x:37:37:Operator:/var:/bin/sh  
  8. ftp:x:83:83:ftp:/home/ftp:/bin/sh  
  9. ftp:x:83:83:ftp:/home/ftp:/bin/sh  
  10. nobody:x:99:99:nobody:/home:/bin/sh  
  11. nobody:x:99:99:nobody:/home:/bin/sh  
  12. sshd:x:103:99:Operator:/var:/bin/sh  
  13. sshd:x:103:99:Operator:/var:/bin/sh  
  14. #  
发现每一行打印了两次,我们使用-n选项关闭默认的输出:
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #sed -n 'p' passwd  
  2. root:x:0:0:root:/root:/bin/sh  
  3. proxy:x:13:13:proxy:/bin:/bin/sh  
  4. operator:x:37:37:Operator:/var:/bin/sh  
  5. ftp:x:83:83:ftp:/home/ftp:/bin/sh  
  6. nobody:x:99:99:nobody:/home:/bin/sh  
  7. sshd:x:103:99:Operator:/var:/bin/sh  
# awk实现对比:
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #awk '{print}' passwd  
  2. root:x:0:0:root:/root:/bin/sh  
  3. proxy:x:13:13:proxy:/bin:/bin/sh  
  4. operator:x:37:37:Operator:/var:/bin/sh  
  5. ftp:x:83:83:ftp:/home/ftp:/bin/sh  
  6. nobody:x:99:99:nobody:/home:/bin/sh  
  7. sshd:x:103:99:Operator:/var:/bin/sh  
  8. #  
使用sed不一定要打印所有行出来,我们可以定位到某一行对其进行操作,使用s e d在文件中定位文本的方式:
x                         x为一行号,如 1
x,y                         表示行号范围从x到y,如2,5表示从第2行到第5行
/pattern/                     查询包含模式的行。例如 / d i s k /或/[a-z]/ 
/pattern /pattern /             查询包含两个模式的行。例如 / d i s k / d i s k s /
pattern/ , x                 在给定行号上查询包含模式的行。如 / r i b b o n / , 3
x , /pattern/                 通过行号和模式查询匹配行。 3 . / v d u /
x,y!                        查询不包含指定行号 x和y的行。1 , 2 !
2)    打印第3行:
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #sed -n '3p' passwd  
  2. operator:x:37:37:Operator:/var:/bin/sh  
  3. #  
awk实现对比:
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #awk '{if(NR==3)print}' passwd  
  2. operator:x:37:37:Operator:/var:/bin/sh  
  3. #  
3)    打印2到4行:
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #sed -n '2,4p' passwd  
  2. proxy:x:13:13:proxy:/bin:/bin/sh  
  3. operator:x:37:37:Operator:/var:/bin/sh  
  4. ftp:x:83:83:ftp:/home/ftp:/bin/sh  
  5. #  
awk实现对比: 
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #awk '{if(NR<=4 && NR>=2)print}' passwd  
  2. proxy:x:13:13:proxy:/bin:/bin/sh  
  3. operator:x:37:37:Operator:/var:/bin/sh  
  4. ftp:x:83:83:ftp:/home/ftp:/bin/sh  
  5. #  
4)    打印匹配行
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #sed -n '/var/p' passwd  
  2. operator:x:37:37:Operator:/var:/bin/sh  
  3. sshd:x:103:99:Operator:/var:/bin/sh  
  4. #   
awk实现对比:
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #awk '/var/{print}' passwd  
  2. operator:x:37:37:Operator:/var:/bin/sh  
  3. sshd:x:103:99:Operator:/var:/bin/sh  
  4. #  
5)    打印最后一行
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #sed -n '$p' passwd  
  2. sshd:x:103:99:Operator:/var:/bin/sh  

2.    “=”命令,打印行号
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #sed -n '/var/=' passwd  
  2. 3  
  3. 6  
awk实现对比:
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #awk '/var/{print NR}' passwd  
  2. 3  
  3. 6  
如果打印行号及匹配行,必须使用两个sed命令,并使用 e选项。第一个命令打印模式匹配行,第二个使用 =选项打印行号,格式为 sed -n -e /pattern/p -e /pattern/=。
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #sed -n -e '/var/p' -e '/var/=' passwd  
  2. operator:x:37:37:Operator:/var:/bin/sh  
  3. 3  
  4. sshd:x:103:99:Operator:/var:/bin/sh  
  5. 6  
  6. #  
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #awk '/var/{print $0 "\n" NR}' passwd  
  2. operator:x:37:37:Operator:/var:/bin/sh  
  3. 3  
  4. sshd:x:103:99:Operator:/var:/bin/sh  
  5. 6  
  6. #  
3.    \a命令,在指定行后附加新文本
使用符号a \,可以将指定文本一行或多行附加到指定行后面。文本附加操作时,结果输出在标准输出上。要想在附加操作后编辑文本,必须保存文件,然后运行另一个 s e d 命令编辑它。这时文件的内容又被移至缓冲区。
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #sed '/root/a\this line is add by sed\haha' passwd  
  2. root:x:0:0:root:/root:/bin/sh  
  3. this line is add by sedhaha  
  4. proxy:x:13:13:proxy:/bin:/bin/sh  
  5. operator:x:37:37:Operator:/var:/bin/sh  
  6. ftp:x:83:83:ftp:/home/ftp:/bin/sh  
  7. nobody:x:99:99:nobody:/home:/bin/sh  
  8. sshd:x:103:99:Operator:/var:/bin/sh  
  9. #  
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #awk '{print;if(/root/)print"this line is add by awk"}' passwd  
  2. root:x:0:0:root:/root:/bin/sh  
  3. this line is add by awk  
  4. proxy:x:13:13:proxy:/bin:/bin/sh  
  5. operator:x:37:37:Operator:/var:/bin/sh  
  6. ftp:x:83:83:ftp:/home/ftp:/bin/sh  
  7. nobody:x:99:99:nobody:/home:/bin/sh  
  8. sshd:x:103:99:Operator:/var:/bin/sh  
  9. #  
4.    i\命令,和\a命令类似,只是插入文本在匹配行前一行
5.    \c命令,修改指定行
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #sed '/root/c\this line is modify by sed\h' passwd  
  2. this line is modify by sedh  
  3. proxy:x:13:13:proxy:/bin:/bin/sh  
  4. operator:x:37:37:Operator:/var:/bin/sh  
  5. ftp:x:83:83:ftp:/home/ftp:/bin/sh  
  6. nobody:x:99:99:nobody:/home:/bin/sh  
  7. sshd:x:103:99:Operator:/var:/bin/sh  
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #awk '{if(/root/){print"this line is modify by awk"}else {print}}' passwd  
  2. this line is modify by awk  
  3. proxy:x:13:13:proxy:/bin:/bin/sh  
  4. operator:x:37:37:Operator:/var:/bin/sh  
  5. ftp:x:83:83:ftp:/home/ftp:/bin/sh  
  6. nobody:x:99:99:nobody:/home:/bin/sh  
  7. sshd:x:103:99:Operator:/var:/bin/sh  
  8. #  
6.    d命令,删除匹配行
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #sed '1,4d' passwd  
  2. nobody:x:99:99:nobody:/home:/bin/sh  
  3. sshd:x:103:99:Operator:/var:/bin/sh  
  4. #  
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #awk '{if(NR>4)print}' passwd  
  2. nobody:x:99:99:nobody:/home:/bin/sh  
  3. sshd:x:103:99:Operator:/var:/bin/sh  
  4. #  
7.    s命令,替换行文本
格式为:[address [,address]] s/ pattern-to-find /replacement-pattern/[g p w n]
该命令在指定行([address [,address]]),使用S命令,将符合模式pattern-to-find的文本替换为文本replacement-pattern,p选项将打印出替换的行,g选项替换全局所有出现模式,缺省情况下只替换第一次出现模式。w  文件名 使用此选项将输出定向到一个文件。
现在我们来替换文件第1,2行的bin字符串,替换为sedtest:
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. # sed  '1,2s/bin/sedtest/' passwd              
  2. root:x:0:0:root:/root:/sedtest/sh  
  3. proxy:x:13:13:proxy:/sedtest:/bin/sh  
  4. operator:x:37:37:Operator:/var:/bin/sh  
  5. ftp:x:83:83:ftp:/home/ftp:/bin/sh  
  6. nobody:x:99:99:nobody:/home:/bin/sh  
  7. sshd:x:103:99:Operator:/var:/bin/sh  
我们可以使用sed的-n选项以及s命令的p选项来仅仅打印被替换的行:
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. # sed -n '1,2s/bin/sedtest/p' passwd  
  2. root:x:0:0:root:/root:/sedtest/sh  
  3. proxy:x:13:13:proxy:/sedtest:/bin/sh  
使用s命令的g选项可以替换当前行所有符合模式的地方:
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. # sed -n '1,2s/bin/sedtest/pg' passwd  
  2. root:x:0:0:root:/root:/sedtest/sh  
  3. proxy:x:13:13:proxy:/sedtest:/sedtest/sh  
该命令使用awk实现较复杂。
8.    r命令,从另一个文件中读文本
从new.txt文件读取内容附加到文件符合模式的指定行后面。
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. # sed '3r new.txt' passwd  
  2. root:x:0:0:root:/root:/bin/sh  
  3. proxy:x:13:13:proxy:/bin:/bin/sh  
  4. operator:x:37:37:Operator:/var:/bin/sh  
  5. this line from new.txt  
  6. ftp:x:83:83:ftp:/home/ftp:/bin/sh  
  7. nobody:x:99:99:nobody:/home:/bin/sh  
  8. sshd:x:103:99:Operator:/var:/bin/sh  
此操作使用awk较复杂。
9.    q命令,在符合模式行后面退出
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. # sed '/Operator/q' passwd  
  2. root:x:0:0:root:/root:/bin/sh  
  3. proxy:x:13:13:proxy:/bin:/bin/sh  
  4. operator:x:37:37:Operator:/var:/bin/sh  
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. # awk '{print;if (NR >= 3)exit}' passwd  
  2. root:x:0:0:root:/root:/bin/sh  
  3. proxy:x:13:13:proxy:/bin:/bin/sh  
  4. operator:x:37:37:Operator:/var:/bin/sh  
10.    l命令,显示文件控制字符
对之前使用new.txt文件稍作修改(加入一些控制字符)如下:
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. # cat new.txt  
  2. this line from new.txt  
  3. kkh  
  4.   
  5. #   
使用l命令显示如下:
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. # sed  -n 'l' new.txt  
  2. this line from new.txt\033[B$  
  3. kkh$  
  4. \r$  
  5. #  
Awk未发现有此功能。
11.    sed使用正则表达式进复杂替换
删除行首字母:
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. # sed 's/^[a-z]*//g'  passwd  
在匹配文本后面增加文本:
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. # sed 's/[0-9][0-9]:/&8902:/g'  passwd  
  2. root:x:0:0:root:/root:/bin/sh  
  3. proxy:x:13:8902:13:8902:proxy:/bin:/bin/sh  
  4. operator:x:37:8902:37:8902:Operator:/var:/bin/sh  
  5. ftp:x:83:8902:83:8902:ftp:/home/ftp:/bin/sh  
  6. nobody:x:99:8902:99:8902:nobody:/home:/bin/sh  
  7. sshd:x:103:8902:99:8902:Operator:/var:/bin/sh  
对password文件做如下操作:
a.    删除已:分隔的第一列
b.    将所有:替换为空格
c.    删除行尾sh
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. # sed 's/^[a-z]*://g' passwd  |  sed 's/:/ /g' | sed 's/sh$//g'  
  2. x 0 0 root /root /bin/  
  3. x 13 13 proxy /bin /bin/  
  4. x 37 37 Operator /var /bin/  
  5. x 83 83 ftp /home/ftp /bin/  
  6. x 99 99 nobody /home /bin/  
  7. x 103 99 Operator /var /bin/  
删除行首两字符:
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. # echo "hello sed." | sed 's/^..//g'  
  2. llo sed.  
删除行尾两字符:
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. # echo "hello sed." | sed 's/..$//g'  
  2. hello se  
在sed字符串后面添加字符串” world”:
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. # echo "hello sed." | sed 's/sed/& world/g'  
  2. hello sed world.  
    awk和sed的比较,我目前片面看来,sed更适合修改编辑文件,尤其是要修改行中某一字符串的时候很方便;而awk更适合用来取出每一行按指定分割符号分割出来的信息。
awk更复杂,感觉更像一种编程语言一样,而sed更像一个工具,用少量代码可以轻松搞定一些处理。这两工具各取所长,有的时候可以联合使用,处理起文本来就更好了。



FROM : http://blog.csdn.net/shallnet/article/details/38925653

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值