sed的一些用法总结

(转自http://www.dbonline.cn/source/oracle/20031224/UNIX_text%20command%20sed.html)

转比写快多啦唉

文本处理命令之sed

作者:forest

       
测试:

以 Redhat6.0 为测试环境
事实上在solaris下的sed命令要比linux强,但因为没有测试
环境,我这里只给在linux下经过测试的用法。

目录:

★ 命令行参数简介
★ 首先假设我们有这样一个文本文件 sedtest.txt
★ 输出指定范围的行 p
★ 在每一行前面增加一个制表符(^I)
★ 在每一行后面增加--end
★ 显示指定模式匹配行的行号 [/pattern/]=
★ 在匹配行后面增加文本 [/pattern/]a\ 或者 [address]a\
★ 删除匹配行 [/pattern/]d 或者 [address1][,address2]d
★ 替换匹配行 [/pattern/]c\ 或者 [address1][,address2]c\
★ 在匹配行前面插入文本 [/pattern/]i\ 或者 [address]i\
★ 替换匹配串(注意不再是匹配行) [addr1][,addr2]s/old/new/g
★ 限定范围后的模式匹配
★ 指定替换每一行中匹配的第几次出现
★ &代表最后匹配
★ 利用sed修改PATH环境变量
★ 测试并提高sed命令运行效率
★ 指定输出文件 [address1][,address2]w outputfile
★ 指定输入文件 [address]r inputfile
★ 替换相应字符 [address1][,address2]y/old/new/
★ !号的使用
★ \c正则表达式c 的使用
★ sed命令中正则表达式的复杂性
★ 转换man手册成普通文本格式(新)
★ sed的man手册(用的就是上面的方法)

★ 命令行参数简介

sed
-e script 指定sed编辑命令
-f scriptfile 指定的文件中是sed编辑命令
-n 寂静模式,抑制来自sed命令执行过程中的冗余输出信息,比如只
显示那些被改变的行。

不明白?不要紧,把这些肮脏丢到一边,跟我往下走,不过下面的介绍里
不包括正则表达式的解释,如果你不明白,可能有点麻烦。

★ 首先假设我们有这样一个文本文件 sedtest.txt

cat > sedtest.txt
Sed is a stream editor
----------------------
A stream editor is used to perform basic text transformations on an input stream
--------------------------------------------------------------------------------
While in some ways similar to an editor which permits scripted edits (such as ed
)
,
--------------------------------------------------------------------------------
-
-
sed works by making only one pass over the input(s), and is consequently more
-----------------------------------------------------------------------------
efficient. But it is sed's ability to filter text in a pipeline which particular
l
y
--------------------------------------------------------------------------------
-

★ 输出指定范围的行 p other types of editors.

sed -e "1,4p" -n sedtest.txt
sed -e "/from/p" -n sedtest.txt
sed -e "1,/from/p" -n sedtest.txt

★ 在每一行前面增加一个制表符(^I)

sed "s/^/^I/g" sedtest.txt

注意^I的输入方法是ctrl-v ctrl-i

单个^表示行首

★ 在每一行后面增加--end

sed "s/$/--end/g" sedtest.txt

单个$表示行尾

★ 显示指定模式匹配行的行号 [/pattern/]=

sed -e '/is/=' sedtest.txt

1
Sed is a stream editor
----------------------
3
A stream editor is used to perform basic text transformations on an input stream
--------------------------------------------------------------------------------
While in some ways similar to an editor which permits scripted edits (such as ed
)
,
--------------------------------------------------------------------------------
-
-
7
sed works by making only one pass over the input(s), and is consequently more
-----------------------------------------------------------------------------
9
efficient. But it is sed's ability to filter text in a pipeline which particular
l
y
--------------------------------------------------------------------------------
-
-
意思是分析sedtest.txt,显示那些包含is串的匹配行的行号,注意11行中出现了is字符串
这个输出是面向stdout的,如果不做重定向处理,则不影响原来的sedtest.txt

★ 在匹配行后面增加文本 [/pattern/]a\ 或者 [address]a\
^D

sed -f sedadd.script sedtest.txt

Sed is a stream editor

A stream editor is used to perform basic text transformations on an input stream

While in some ways similar to an editor which permits scripted edits (such as ed
)
,
--------------------------------------------------------------------------------
-
-
sed works by making only one pass over the input(s), and is consequently more
-----------------------------------------------------------------------------
efficient. But it is sed's ability to filter text in a pipeline which particular
l
y
--------------------------------------------------------------------------------
-
-
[scz@ /home/scz/src]> sed -e "a\\
+++++++++
---------------------------------------------

找到包含from字符串的行,在该行的下一行增加+++++++++。
这个输出是面向stdout的,如果不做重定向处理,则不影响原来的sedtest.txt

很多人想在命令行上直接完成这个操作而不是多一个sedadd.script,不幸的是,这需要用?nbsp;
?nbsp;
续行符\,

[scz@ /home/scz/src]> sed -e "/from/a\\
> +++++++++" sedtest.txt

[scz@ /home/scz/src]> sed -e "a\\
> +++++++++" sedtest.txt

上面这条命令将在所有行后增加一个新行+++++++++

[scz@ /home/scz/src]> sed -e "1 a\\
> +++++++++" sedtest.txt

把下面这两行copy/paste到一个shell命令行上,效果一样

+++++++++" sedtest.txt

[address]a\ 只接受一个地址指定

对于a命令,不支持单引号,只能用双引号,而对于d命令等其他命令,同时


★ 删除匹配行 [/pattern/]d 或者 [address1][,address2]d

sed -e '/---------------------------------------------/d' sedtest.txt

Sed is a stream editor

A stream editor is used to perform basic text transformations on an input stream
While in some ways similar to an editor which permits scripted edits (such as ed
)
,
sed works by making only one pass over the input(s), and is consequently more
efficient. But it is sed's ability to filter text in a pipeline which particular
l

y

sed -e '6,10d' sedtest.txt
删除6-10行的内容,包括6和10

sed -e "2d" sedtest.txt
删除第2行的内容

sed "1,/^$/d" sedtest.txt
删除从第一行到第一个空行之间的所有内容
注意这个命令很容易带来意外的结果,当sedtest.txt中从第一行开始并没有空行,则sed删
?nbsp;
?nbsp;

sed "1,/from/d" sedtest.txt
删除从第一行到第一个包含from字符串的行之间的所有内容,包括第一个包含
from字符串的行。

★ 替换匹配行 [/pattern/]c\ 或者 [address1][,address2]c\

sed -e "/is/c\\
**********" sedtest.txt

寻找所有包含is字符串的匹配行,替换成**********

**********
----------------------
**********
--------------------------------------------------------------------------------
While in some ways similar to an editor which permits scripted edits (such as ed
)
,
--------------------------------------------------------------------------------
-
-
**********
-----------------------------------------------------------------------------
**********
--------------------------------------------------------------------------------
-

sed -e "1,11c\\
**********" sedtest.txt----------------------
在1-12行内搜索所有from字符串,分别替换成****字符串

★ 限定范围后的模式匹配

sed "/But/s/is/are/g" sedtest.txt
对那些包含But字符串的行,把is替换成are

sed "/is/s/t/T/" sedtest.txt
对那些包含is字符串的行,把每行第一个出现的t替换成T

sed "/While/,/from/p" sedtest.txt -n
输出在这两个模式匹配行之间的所有内容

★ 指定替换每一行中匹配的第几次出现

sed "s/is/are/5" sedtest.txt
把每行的is字符串的第5次出现替换成are

★ &代表最后匹配

sed "s/^$/(&)/" sedtest.txt
给所有空行增加一对()

sed "s/is/(&)/g" sedtest.txt
给所有is字符串外增加()

sed "s/.*/(&)/" sedtest.txt
给所有行增加一对()

sed "/is/s/.*/(&)/" sedtest.txt
给所有包含is字符串的行增加一对()

★ 利用sed修改PATH环境变量

先查看PATH环境变量
[scz@ /home/scz/src]> echo $PATH
/usr/bin:/usr/bin:/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/X11R6/bin:.

去掉尾部的{ :/usr/X11R6/bin:. }
[scz@ /home/scz/src]> echo $PATH | sed "s/^\(.*\):\/usr[/]X11R6\/bin:[.]$/\1/"
/usr/bin:/usr/bin:/bin:/usr/local/bin:/sbin:/usr/sbin

去掉中间的{ :/bin: }
[scz@ /home/scz/src]> echo $PATH | sed "s/^\(.*\):\/bin:\(.*\)$/\1\2/"
/usr/bin:/usr/bin/usr/local/bin:/sbin:/usr/sbin:/usr/X11R6/bin:.

[/]表示/失去特殊意义
\/同样表示/失去意义
\1表示子匹配的第一次出现
\2表示子匹配的第二次出现
\(.*\)表示子匹配

去掉尾部的:,然后增加新的路径
PATH=`echo $PATH | sed 's/\(.*\):$/\1/'`:$HOME/src
注意反引号`和单引号'的区别。

★ 测试并提高sed命令运行效率

time sed -n "1,12p" webkeeper.db > /dev/null
time sed 12q webkeeper.db > /dev/null
可以看出后者比前者效率高。

[address]q 当碰上指定行时退出sed执行

★ 指定输出文件 [address1][,address2]w outputfile

sed "1,10w sed.out" sedtest.txt -n
将sedtest.txt中1-10行的内容写到sed.out文件中。

★ 指定输入文件 [address]r inputfile

sed "1r sedappend.txt" sedtest.txt
将sedappend.txt中的内容附加到sedtest.txt文件的第一行之后

★ 替换相应字符 [address1][,address2]y/old/new/

sed "y/abcdef/ABCDEF/" sedtest.txt
将sedtest.txt中所有的abcdef小写字母替换成ABCDEF大写字母。

★ !号的使用

sed -e '3,7!d' sedtest.txt
删除3-7行之外的所有行

sed -e '1,/from/!d' sedtest.txt
找到包含from字符串的行,删除其后的所有行

★ \c正则表达式c 的使用

sed -e "\:from:d" sedtest.txt
等价于 sed -e "/from/d" sedtest.txt

★ sed命令中正则表达式的复杂性

cat > sedtest.txt
^\/[}]{.*}[\(]$\)
^D

如何才能把该行替换成
\(]$\)\/[}]{.*}^[

★ 转换man手册成普通文本格式(新)

man sed | col -b > sed.txt
sed -e "s/^H//g" -e "/^$/d" -e "s/^^I/ /g" -e "s/^I/ /g" sed.txt > sedman
.
txt
删除所有退格键、空行,把行首的制表符替换成8个空格,其余制表符替换成一个空格。