非交互式流编辑器sed

[TOC]

替换

使用s全局替换foo为bar:

sed 's/foo/bar/g'

也可以仅仅替换从第10到20行:

sed '10,20s/foo/bar/'

替换语句可以并列多条:

sed 's/foo1/bar1/;s/foo2/bar2/'

遇到需要转义定界符/的时候,可以使用其他字符替代:

sed 's!/bin/bash!/bin/sh!'

注意sed中正则表达式使用到的特殊字符 .*{}[]^$\+?| 必须要转义。

如果要替换括号,需要使用 -e 参数:

sed -e 's/(/X'

删除

使用d删除文件的第10到20行:

sed '10,20d' file.txt

删除匹配到foo的行:

sed '/foo/d' file.txt

插入

使用i将foo插入到文件开头:

sed '1ifoo' file.txt

使用a将foo插入到文件末尾:

sed '$afoo' file.txt

更改

使用c将第2行更改成foo:

sed '2cfoo' file.txt

将匹配到foo的行,更改成bar:

sed '/foo/cbar' file.txt

打印

使用参数-n打印匹配到foo的行,类似awk:

sed -n '/foo/p' file.txt

打印从第10到20行:

sed -n '10,20p' file.txt

文件操作

使用参数-i会将原始文件做一个备份,然后新的输出会替换到原始文件;如果该参数接收一个空字符串参数,则不产生备份,输出结果直接覆盖原始文件。

比如,全局替换foo为bar后,将原始文件备份成file.txt.bak:

sed -i.bak 's/foo/bar/g' file.txt

直接覆盖原始文件:

sed -i'' 's/foo/bar/g' file.txt

示例

在FreeBSD里边检查重复安装的包,可以用这个脚本:

pkg_info | sort | sed -e 's/-[0-9].*$//' | uniq -c | grep -v '^[[:space:]]*1'

用wget下载了一个整站,可惜发觉他们居然没有设置charset,用sed来完善一下,先下载:

wget -m -E -Pluo -k http://shokn.com

然后用下边的命令给每个html文件设置charset:

find $1 -name "*html" -type f -print | xargs sed -i'' '/<\/title>/a\\<meta\ http-equiv="Content-Type"\ content="text\/html;\ charset=utf-8">'