# sed -n '/Dec 28 15:15:00/,$p' filename //查询某段时间到现在的日志
sed -n ‘/2010-11-17 09:[0-9][0-9]:[0-9][0-9]/,/2010-11-17 16:[0-9][0-9]:[0-9][0-9]/p’ logfile
reference from: blog.jobbole.com/109088/
ED的英文全称是Stream EDitor,它是一个简单而强大的文本解析转换工具,在1973-1974年期间由贝尔实验室的Lee E. McMahon开发,今天,它已经运行在所有的主流操作系统上了
SED的典型用途:
文本替换
选择性的输出文本文件
从文本文件的某处开始编辑
无交互式的对文本文件进行编辑等
工作流:
读取: SED从输入流(文件,管道或者标准输入)中读取一行并且存储到它叫做 模式空间(pattern buffer) 的内部缓冲区
执行: 默认情况下,所有的SED命令都在模式空间中顺序的执行,除非指定了行的地址,否则SED命令将会在所有的行上依次执行
显示: 发送修改后的内容到输出流。在发送数据之后,模式空间将会被清空。
在文件所有的内容都被处理完成之前,上述过程将会重复执行
测试文本:
$vibooks.txt
1)AStormofSwords,GeorgeR.R.Martin,1216
2)TheTwoTowers,J.R.R.Tolkien,352
3)TheAlchemist,PauloCoelho,197
4)TheFellowshipoftheRing,J.R.R.Tolkien,432
5)ThePilgrimage,PauloCoelho,288
6)AGameofThrones,GeorgeR.R.Martin,864
基础语法:
#sed -e '1d' -e '2d' -e '5d' filename //移除指定的行,删除三行,使用-e选项指定三个独立y要执行的命令
还可以将多个SED命令写在一个文本文件中,然后将该文件作为SED命令的参数,SED可以对模式空间中的内容执行文件中的每一个命令,下面的例子描述了SED的第二种用法.
首先,创建一个包含SED命令的文本文件
$echo -e "1d\n2d\n5d" >commands.txt
$cat commands.txt
1d
2d
5d
接下来构造一个SED命令去执行该操作
$sed -f commands.txt books.txt //-f指定包含要执行的命令基本文件
3)The Alchemist, Paulo Coelho,197
4)The Fellowship of the Ring, J.R.R.Tolkien, 432
6)A Game ofT hrones, George R.R.Martin, 864
$sed 'p' books.txt
$sed -n 'p' books.txt
//默认情况下,SED将会输出模式空间中的内容,另外,我们的命令中包含了输出命令p,因此每一行被打印两次。但是不要担心,SED提供了-n参数用于禁止自动输出模式空间的每一行的行为
行寻址:
#sed -n '2,5 p' books.txt //输出2-5行的内容
# sed -n '$ p' books.txt //输出文件最后一行
# sed -n '3,$ p' books.txt //输出文件第三行到最后一行
# sed -n '3,+2 p' books.txt //输出第三行开始的下面2行
#sed -n '1~2 p' books.txt //输出文件中的偶数行
#sed -n '2~2 p' books.txt //输出文件中的偶数行。使用波浪线操作符(~)指定地址范围,它使用M~N的形式,它告诉SED应该处理M行开始的每N行。
#sed -n '/Paulo/ p' books.txt //输出所有作者为Paulo Coelho的书籍
#sed -n '/Alchemist/, 5 p' books.txt //从第一次匹配到Alchemist开始输出,直到第5行为止
#sed -n '/Two/, +4 p' books.txt //从第一次Two出现的位置开始输出接下来的4行
删除命令d:
# sed '2,4 d' books.txt //移除第2-4行
#sed '/patter1/, /patter2/d' filename //移除所有以pattert1和patter2开头的行
文件写入命令w:
#sed -n 'w books.bak' books.txt //使用file操作符的时候要小心,当提供了文件名但是文件(books.bak)不存在的时候它会自动创建,如果已经存在的话则会覆盖原文件的内容
验证一下两个文件的内容是否相同:
#diffbooks.txtbooks.bak
#echo$?
# sed -n '2~2 w complex_book,bank' books.txt //存储文件中的奇数行到另一个文件
#sed -n -e '/Martin/ w Martin.txt' -e '/Paulo/ w Paulo.txt' -e '/Tolkien/ w Tolkien.txt' books.txt //存储所有独立作者的书到单独的文件
# sed '4 a 7) Adultry, Paulo Coelho, 234' books.bank //在命令部分,4指的是行号,a 是append命令,剩余部分为要追加的文本。在第四行之后追加一本新书
# sed '/The Alchemist/ a 7) Adultry, Paulo Coelho, 234' books.bank //除了行号,我们也可以使用文本模式指定地址,例如,在匹配 The Alchemist 的行之后追加文本
行替换命令c:
SED通过c提供了change和replace命令,该命令帮助我们使用新文本替换已经存在的行,当提供行的地址范围时,所有的行都被作为一组被替换为单行文本,下面是该命令的语法
# sed '3 c 3) Adultry, Paulo Coelho, 324' books.bank //替换文本中的第三行为新的内容
# sed '/The Alchemist/ c 3) Adultry, Paulo Coelho, 325' books.bank //SED也接受模式作为地址
# sed '4, 6 c 4) Adultry, Paulo Coelho, 324' books.bank //多行替换也是支持的,将第4-6行内容替换为单行。
# sed '4 i 7) Adultry, Paulo Coelho, 324' books.bank //在第四行前插入新的一行
输出隐藏字符命令l
直接观察区分出单词是通过空格还是tab进行分隔,使用l命令(英文字母L的小写)可以显示文本中的隐藏字符(例如\t或者$字符)。
测试该命令,先将books.bank中的空格替换为tab。
[root@system1 ~]# sed 's/ /\t/g' books.bank > junk.txt
[root@system1 ~]# sed -n 'l' junk.txt
一个很有趣的特性:可以使用它来实现文本按照指定的宽度换行。
[root@system1 ~]# sed -n 'l 25' books.bank //按照每行25个字符进行换行,如果指定这个数字为0的话,则只有在存在换行符的情况下才进行换行。(l命令是GNU-SED的一部分,其它的一些变体中可能无法使用该命令。)
退出命令q
以使用Quit命令退出当前的执行流(q命令不支持地址范围,只支持单个地址匹配。默认情况下SED会按照读取、执行、重复的工作流执行,但当它遇到q命令的时候,它会退出当前的执行流。)
$sed '3 q' books.txt
$sed '/The Alchemist/ q' books.txt
q命令也支持提供一个value,这个value将作为程序的返回代码返回
$sed '/The Alchemist/ q 100' books.txt
$echo $?
文件读取命令r
可以让SED使用Read命令从外部文件中读取内容并且在满足条件的时候显示出来。r命令和文件名之间必须只有一个空格。
//下面的示例会打开junk.txt文件,将其内容插入到books.txt文件的第三行之后
$echo "This is junk text." > junk.txt
$sed '3 r junk.txt' books.txt
//r命令也支持地址范围,例如3, 5 r junk.txt会在第三行,第四行,第五行后面分别插入junk.txt的内容
执行外部命令e
[root@system1 ~]# sed '3 e date' books.bank //在第三行之前执行date命令
其实它的command参数是可选的。在没有提供外部命令的时候,SED会将模式空间中的内容作为要执行的命令。
$echo-e"date\ncal\nuname">commands.txt
$catcommands.txt
date
cal
uname
$sed'e'commands.txt
排除命令!
感叹号命令(!)用来排除命令,也就是让原本会起作用的命令不起作用。
# sed -n '/Paulo/!p' books.bank //只输出不匹配Paulo的行
[root@system1 ~]# sed -n '1!G; h; $p' books.bank //该命令实现了类似tac命令类似的输出,将文本内容倒序输出。
特殊字符:
在SED中提供了两个可以用作命令的特殊字符:=和&。
[root@system1 ~]# sed '=' books.bank //为每一行输出行号
[root@system1 ~]# sed '/Paulo/ =' books.bank //匹配Paulo的行输出行号
[root@system1 ~]# sed -n '$ =' books.bank //最后一行输出行号,可以用于输出文件总共有多少行。
特殊字符&用于存储匹配模式的内容,通常与替换命令s一起使用。
[root@system1 ~]# sed 's/[[:digit:]]/book number &/' books.bank //匹配每一行第一个数字,在其前面添加Book number
字符串:替换命令s
[root@system1 ~]# sed 's/,/|/g' books.bank //用|替换,
如果对匹配模式(或地址范围)的行进行替换,则只需要在s命令前添加地址即可。比如只替换匹配The Pilgrimage的行:#sed ‘/The Pilgrimage/ s/,/ | /g’ books.bank
数字n: 只替换第n次匹配,比如sed ‘s/,/ | /2’ books.txt,只替换每行中第二个逗号
p:只输出改变的行,比如sed -n ‘s/Paulo Coelho/PAULO COELHO/p’ books.txt
w:存储改变的行到文件,比如sed -n ‘s/Paulo Coelho/PAULO COELHO/w junk.txt’ books.txt
i:匹配时忽略大小写,比如sed -n ‘s/pAuLo CoElHo/PAULO COELHO/pi’ books.txt
常用代码段
模拟cat命令比较简单,有下面两种方式
[root@system1 ~]# sed '' books.bank
[root@system1 ~]# sed -n 'p' books.bank
[root@system1 ~]# echo -e 'Line #1\n\n\nLine #2' | sed '/^$/d' //移除空行
[root@system1 ~]# echo -e 'Line #1\n\n\nLine #2' | sed '/./,/^$/!d' /删除连续空行
[root@system1 ~]# echo -e "\nLine #1\n\nLine #2" | sed '/./,$!d' //删除开头的空行
[root@system1 ~]# echo -e "\nLine #1\nLine #2\n\n" | sed ':start /^\n*$/{$d; N; b start }' //删除结尾的空行
#sed ‘s/]*>//g ; /^$/d’ html.txt //过滤所有的html标签
#sed 's|//.*||g' hello.cpp //移除注释
[root@system1 ~]# sed '3,5 s/^/#/' hello.sh //为3-5行添加注释
实现Wc -l命令
#wc-l hello.cpp
#sed -n '$ =' hello.cpp
模拟实现head命令
#head books.txt
#sed '10 q' books.txt
模拟tail -1输出文件的最后一行
# tail -1 books.bank
# sed -n '$p' books.bank
模拟Dos2unix命令
在DOS环境中,换行符是使用CR/LF两个字符一起表示的,下面命令模拟了dos2unix命令转换这些换行符为UNIX换行符。在GNU/Linux环境中,CR/LF通常使用”^M”(不是简单的两个符号组合,请使用快捷键Ctrl+v,Ctrl+m输入)进行表示。
$echo -e "Line #1\r\nLine #2\r" > test.txt
$file test.txt
test.txt:ASCIItext,withCRLFlineterminators
$sed 's/^M$//' test.txt > new.txt
$file new.txt
new.txt:ASCIItext
$cat -vte new.txt
Line#1$
Line#2$