sed (2)

1.Sed是一个非交互性文本流编辑器。sed与awk类似,执行时可以使用命令行;可以将

sed命令写入一个文件,然后调用sed;也可以将sed命令插入一个脚本文件并使脚本文件可执行。
一般情况下sed并不与初始化文件打交道,他操作的只是一个拷贝,如果要修改原文件那么就要用-i选项。

2.sed的工作过程:sed逐行处理输入文件,首先从输入文件读入一行到模式空间
也就是临时缓冲区,在该行上执行所有命令,将结果发送到指定的区域(stdout或指定的文件中)。当我们执行的是
一个sed脚本文件,那么我们就从输入文件中读入一行数据到模式空间,执行脚本文件中的所有命令,然后在继续读取输入
文件的下一行,并开始用sed脚本文件中的命令去处理文本。

3.sed定位文本的方法有两种:一种是行号,一种是正则表达式。

4.命令与选项:sed命令告诉sed如何处理由地址指定的各输入行。如果没有指定地址,sed就会处理所有的输入行。
sed的命令包括:
a/ :在当前行之后添加。追加。
c/ :用新文本替换当前行的文本。
d :删除当前行
i/ :在当前行之前插入文本
p :打印行
g :在行内进行全局替换
w :将行写入文件
s :用一个字符串替换另一个
命令还有很多,这里只列出了比较常用的几个。
sed的选项:
-e :允许多项编辑
-f :指定sed脚本文件名
-n :取消默认的输出

4.当没有出现语法错误时sed返回0。出现语法错误时返回非零。

5.
采用下面这个datafiel文件作为示例
along 04075021 1 90
xiaolong 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinlong 0408098 2 jinming 37

1)p命令
along@along-laptop:~/code/shell/sed$ sed '/along/p' datafile
along 04075021 1 90
along 04075021 1 90
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

这是将所有找到的匹配行都打印两遍

along@along-laptop:~/code/shell/sed$ sed -n '/xiao/p' datafile
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
当加上了-n选项时,只打印匹配行。
-n要和 p 配合使用

2)d命令(删除)从模式空间中删除并读入下一行

sed ‘3d’ datafile:删除第三行
along@along-laptop:~/code/shell/sed$ sed '3d' datafile
along 04075021 1 90
xiaoming 04075022 1 92
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

sed ‘3,$d’ datafile(删除第三行到最后一行)
sed '/along/d' datafile(包含模式along的行都被删除,其余行打印)
sed -n '/along/d' datafile(删除包含模式along的行,此时显示内容为空)

3)s命令(替换)
along@along-laptop:~/code/shell/sed$ sed 's/ming/long/g' datafile
along 04075021 1 90
xiaolong 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinlong 0408098 2 jinlong 37
用long替换所有的ming。如果没有g那么将只替换每一行第一个ming。比如(注意观察最后一行):
along@along-laptop:~/code/shell/sed$ sed 's/ming/long/' datafile
along 04075021 1 90
xiaolong 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinlong 0408098 2 jinming 37

sed 's/[9]/&.5/g' datafile (在所有的9后边都加上一个.5)
比如:
along@along-laptop:~/code/shell/sed$ sed 's/9/&.5/g' datafile
along 04075021 1 9.50
xiaoming 04075022 1 9.52
xiaoguang 04075032 2 89.5
chang 04075036 2 79.5
hang 0407509.58 3 70
jinming 040809.58 2 jinming 37
当符号“&”和s一起用的时候,表示在找到的匹配串后边加上相应的串。

紧跟在s命令后边的字符就是查找串和替换串之间的分隔符。分隔符默认是正斜杠,但是可以改变。无论什么字符
只要紧跟这s就成了新的分隔符。
比如:
along@along-laptop:~/code/shell/sed$ sed -n 's#ming#along#gp' datafile
xiaoalong 04075022 1 92
jinalong 0408098 2 jinalong 37

4)定址
along@along-laptop:~/code/shell/sed$ sed -n '1,/ming/p' datafile
along 04075021 1 90
xiaoming 04075022 1 92
从第一行开始打印直到第一次出现ming

along@along-laptop:~/code/shell/sed$ sed -n '2,2p' datafile
xiaoming 04075022 1 92
只打印第二行的内容。


5)-e多重编辑选项。用于sed执行多个编辑命令时将前一个的编辑结果应用到后一个编辑命令上。
along@along-laptop:~/code/shell/sed$ sed -n -e 's/ming/long/' -e 's/long/mn/gp' datafile
amn 04075021 1 90
xiaomn 04075022 1 92
jinmn 0408098 2 jinming 37
这个例子没有任何作用,只是为了说明问题。
首先第一行原来是along,当执行第一条编辑命令时发现无法匹配,于是继续执行第二条编辑命令将long替换为mn。
第二行就不用再说了。
第三行,首先执行第一条编辑命令,发现没有 g 命令,于是就只是将第一个ming替换为long;然后执行第二条编辑命令
此时虽然有 g 这个命令,但是已经于事无补,因为当前行此时只有一个long。所以结果也就理所当然是这样了jinmn 0408098 2 jinming 37。

6)r读文件。sed使用该命令将一个文本文件中的内容加到当前文件的特定位置。
比如:
along@along-laptop:~/code/shell/sed$ cat file
---------Read File------------
along@along-laptop:~/code/shell/sed$ sed '/along/r file' datafile
along 04075021 1 90
---------Read File------------
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

7)w 写文件命令。
sed使用该命令将当前文件中的匹配行写入另外一个文件中。
sed -n ‘/along/w newfile’ datafile
将datafile中包含along的行全部写如newfile文件中。

8)a 追加命令。在当前行之后添加新文本。
比如:
along@along-laptop:~/code/shell/sed$ sed '/along/a/----student----' datafile
along 04075021 1 90
----student----
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

9)i 插入命令。在当前行之前插入新文本。
比如:
along@along-laptop:~/code/shell/sed$ sed '/along/i/----student----' datafile
----student----
along 04075021 1 90
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

10)c 修改命令。sed使用该命令将当前行修改成新文本。
比如:
along@along-laptop:~/code/shell/sed$ sed '/ming/c/----student----' datafile
along 04075021 1 90
----student----
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
----student----

11)n 命令。sed使用该命令获取输入文件的下一行进行处理。
比如:
along@along-laptop:~/code/shell/sed$ cat datafile
along 04075021 1 90
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

along@along-laptop:~/code/shell/sed$ sed '/along/{n;s/ming/long/;}' datafile
along 04075021 1 90
xiaolong 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37
将包含along的文本的下一行中的ming改为long。

12)y 命令。转换。字符按照一对一的方式从左到有进行转换。
sed '1,3y/abc/ABC/' datafile

13)q 命令。退出。
sed ‘5q’ datafile
显示完第5行时退出。

14)暂存和取用:h和g命令。
h:将模式空间的内容复制到暂存缓冲区,即一个特殊的临时缓冲区。暂存缓冲区的当前内容被清除。
H: 将换行符和模式空间的内容追加到暂存缓冲区中,即使暂存缓冲区为空,这个命令也追加换行符。当暂存缓冲区为空时拷贝到暂存缓冲区的内容前边要加上空行,
当暂存缓冲区不为空时,H这个命令就又不再加空行了。 
g:将暂存缓冲区中的内容复制到模式空间中,并将当前的内容清除。
G:将暂存缓冲区内容追加到模式空间。如果暂存缓冲区为空,则将换行符添加到模式空间。

along@along-laptop:~/code/shell/sed$ cat datafile
along 04075021 1 90
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

1》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{h;d;} ' -e '$g' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
xiaoguang 04075032 2 89
首先找到包含xiao的行,以覆盖的方式将其复制到暂存缓冲区,然后删除当前行,最后以覆盖的方式取出。

2》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{H;d;} ' -e '$g' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70

xiaoming 04075022 1 92
xiaoguang 04075032 2 89
找到包含xiao的行,以追加的方式将其复制到暂存缓冲区,然后删除当前行,最后以覆盖的方式取出加在文件末尾。

3》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{H;d;}' -e '${g;s/.//;}' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
比较3和2的不同。

4》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{h;d;}' -e '$G' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37
xiaoguang 04075032 2 89
找到包含xiao的行,以覆盖的方式将其复制到暂存缓冲区,然后删除当前行,最后以追加的方式取出。

5》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{H;d;}' -e '$G' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

xiaoming 04075022 1 92
xiaoguang 04075032 2 89
找到包含xiao的行,以追加的方式将其复制到暂存缓冲区,然后删除当前行,最后以追加的方式取出。

6》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{H;d}' -e '$G' datafile|sed -e '/^$/d'
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
比较5和6的区别。6是清除了空行。

7》现在有文件file:
first line
second line
third line

sed -e '/third/{h;d;}' -e '/first/{G;}'
第1行,第一条命令不匹配,输出第一行;接下来执行第二条命令匹配,所以从暂存空间中取出内容,此时为空所以输出空行。
第二行,第一条不匹配,输出第二行,接下来第二条不匹配
第3行,第一条匹配所以直接执行第一条命令,不输出。接下来执行第二条命令。
故结果:
along@along-laptop:~/code/shell/sed$ sed -e '/third/{h;d;}' -e '/first/{G;}' file
first line

second line


sed -e '/third/{h;d;}' -e '/second/{G;}' file
第一行:第一条命令不匹配,输出第一行;接下来执行第二条命令,不匹配。
第二行:第一条命令不匹配,输出第二行;接下来执行第二条命令,匹配所以从暂存空间中取出内容,此时为空,所以输出空行。
第三行:第一条匹配,不输出,直接删除,并存入暂存空间;第二条不匹配。
故结果:(此时second下面有一个空行)
along@along-laptop:~/code/shell/sed$ sed -e '/third/{h;d;}' -e '/second/{G;}' file
first line
second line

sed -e '/third/{h;d;}' -e '/third/{G;}' file
第一行:第一条命令不匹配,输出第一行;接下来执行第二条命令,不匹配。
第二行:第一条命令不匹配,输出第二行;接下来执行第二条命令,不匹配。
第三行:第一条匹配,不输出,存入暂存空间,并直接从模式空间删除;第二条此时模式空间没有了内容所以也就无法匹配了。
故结果:
along@along-laptop:~/code/shell/sed$ sed -e '/third/{h;d;}' -e '/third/{G;}' file
first line
second line

15)删除空行
现在有文件datafile
along@along-laptop:~/code/shell/sed$ cat datafile
along 04075021 1 90

xiaoming 04075022 1 92

xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37
现在想要删除中间的两个空行和每行前边的空格。其中第一个空行是用回车符造成的。第二个使用空格造成的。
如果使用sed '/^$/d' datafile 那么只能删除第一个空行。要想删除两个空行同时删除空格就要这样写:
sed -e '/^[ ]*$/d' -e 's/^[ ]*//' datafile


16)我有文件gr:
90
ad
a9
#8

执行下面这个sed语句:
along@along-laptop:~/code/shell/sed$ sed -n '/^[^0-9a-z]*[0-9]/{1,/}/p' gr
90
#8
这里说明 90 和我的正则表达式 ^[^0-9a-z]*[0-9]/{1,/} 是匹配的。

^[^0-9a-z]*[0-9]/{1,/} 匹配的是:非数字和小写字母出现0次或多次,中间是任意字符,然后再加上1-n个数字组成的字符串。
而 90这个字符串行首是9 符合行首为 0个非数字和小写字母开头,因此就匹配了。

注意:*是匹配前面的0次或多次。
*是匹配前面的0次或多次。所以要匹配不以数字和小写字母开头,中间任意个字符再加一个或多个数字结尾用正则表达式/^[^0-9a-z].*[0-9]/{1,/}/就可以了。

17.sed直接将修改结果保存到源文件中,需要使用-i参数。 
也就是:sed -i 's/along/good/' sedx
将修改结果保存到另外的文件中要用到重定向或者是w。
也就是:sed 's/good/along/ w newfile' oldfile (会在终端上打印修改后的内容)
或者:sed 's/good/along/' oldfile > newfile (不在终端上打印)
比如下面的例子:
1)直接修改原文件
along@along-laptop:~/code/shell$ cat sedx
good name is along~
along@along-laptop:~/code/shell$ sed -i 's/good/along/' sedx
along@along-laptop:~/code/shell$ cat sedx
along name is along~
2)将结果打印到另外一个文件中。
也就是:sed -i 's/along/good/' sedx
将修改结果保存到另外的文件中要用到重定向或者是w。
along@along-laptop:~/code/shell$ cat sedx
along name is along~
along@along-laptop:~/code/shell$ sed 's/along/good/ w out' sedx
good name is along~
along@along-laptop:~/code/shell$ cat out
good name is along~
along@along-laptop:~/code/shell$ sed 's/good/along/' sedx > out
along@along-laptop:~/code/shell$ cat out
along name is along~

总结:
h:将模式空间的内容复制到暂存缓冲区, 
即一个特殊的临时缓冲区。暂存缓冲区的当前内容被清除。
H: 将换行符和模式空间的内容追加到暂存缓冲区中,即使暂存缓冲区为空,这个命令也追加换行符。当
暂 存缓冲区为空时拷到暂存缓冲区的内容前边要加上空行,当暂存缓冲区不为空时,H这个命令就
又不再加空行了。 
g:将暂存缓冲区中的内容复制到模式空间中,并将当前的内容清除。
G:将暂存缓冲区内容追加到模式空间。如果暂存缓冲区为空,则将换行符添加到模式空间。

along@along-laptop:~/code/shell/sed$ echo "123" | sed 'h;G'
123
123 ;因为h清空了暂存缓冲区,而且h拷贝时不会加上回车所以这里没有空格。
along@along-laptop:~/code/shell/sed$ echo "123" | sed 'H;G'
123

123 ;H拷贝时暂存缓冲区为空时拷贝到暂存缓冲区的内容前边要加上空行,所以这里会出现一个空行。
along@along-laptop:~/code/shell/sed$ echo "123" | sed 'H;g'

123 ;这和上边的一样,H会加上一个回车,同时g会清空模式空间当前的内容
along@along-laptop:~/code/shell/sed$ echo "123" | sed 'h;g'
123 ;h清空了暂存缓冲区,且拷贝时不加回车,g清空了模式空间,所以这里只有一行。
along@along-laptop:~/code/shell/sed$ echo "123" | sed 'H;H;g'

123
123 ;当暂存缓冲区不为空时H就不再加回车了。所以这里只有一个空行。

http://sed.sourceforge.net/sed1line_zh-CN.html

-------------------------------------------------------------------------
SED单行脚本快速参考(Unix 流编辑器) 2005年12月29日

英文标题:USEFUL ONE-LINE SCRIPTS FOR SED (Unix stream editor)
原标题:HANDY ONE-LINERS FOR SED (Unix stream editor)

整理:Eric Pement - 电邮:pemente[at]northpark[dot]edu 版本5.5
译者:Joe Hong - 电邮:hq00e[at]126[dot]com

在以下地址可找到本文档的最新(英文)版本:
http://sed.sourceforge.net/sed1line.txt
http://www.pement.org/sed/sed1line.txt

其他语言版本:
中文 - 
http://sed.sourceforge.net/sed1line_zh-CN.html
捷克语 - http://sed.sourceforge.net/sed1line_cz.html
荷语 - http://sed.sourceforge.net/sed1line_nl.html
法语 - http://sed.sourceforge.net/sed1line_fr.html
德语 - http://sed.sourceforge.net/sed1line_de.html
<!-- 意大利语 - http://sed.sourceforge.net/sed1line_it.html-->
葡语 - http://sed.sourceforge.net/sed1line_pt-BR.html
<!-- 西班牙语 - http://sed.sourceforge.net/sed1line_es.html-->

1.Sed是一个非交互性文本流编辑器。sed与awk类似,执行时可以使用命令行;可以将
sed命令写入一个文件,然后调用sed;也可以将sed命令插入一个脚本文件并使脚本文件可执行。
一般情况下sed并不与初始化文件打交道,他操作的只是一个拷贝,如果要修改原文件那么就要用-i选项。

2.sed的工作过程:sed逐行处理输入文件,首先从输入文件读入一行到模式空间
也就是临时缓冲区,在该行上执行所有命令,将结果发送到指定的区域(stdout或指定的文件中)。当我们执行的是
一个sed脚本文件,那么我们就从输入文件中读入一行数据到模式空间,执行脚本文件中的所有命令,然后在继续读取输入
文件的下一行,并开始用sed脚本文件中的命令去处理文本。

3.sed定位文本的方法有两种:一种是行号,一种是正则表达式。

4.命令与选项:sed命令告诉sed如何处理由地址指定的各输入行。如果没有指定地址,sed就会处理所有的输入行。
sed的命令包括:
a/ :在当前行之后添加。追加。
c/ :用新文本替换当前行的文本。
d :删除当前行
i/ :在当前行之前插入文本
p :打印行
g :在行内进行全局替换
w :将行写入文件
s :用一个字符串替换另一个
命令还有很多,这里只列出了比较常用的几个。
sed的选项:
-e :允许多项编辑
-f :指定sed脚本文件名
-n :取消默认的输出

4.当没有出现语法错误时sed返回0。出现语法错误时返回非零。

5.
采用下面这个datafiel文件作为示例
along 04075021 1 90
xiaolong 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinlong 0408098 2 jinming 37

1)p命令
along@along-laptop:~/code/shell/sed$ sed '/along/p' datafile
along 04075021 1 90
along 04075021 1 90
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

这是将所有找到的匹配行都打印两遍

along@along-laptop:~/code/shell/sed$ sed -n '/xiao/p' datafile
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
当加上了-n选项时,只打印匹配行。
-n要和 p 配合使用

2)d命令(删除)从模式空间中删除并读入下一行

sed ‘3d’ datafile:删除第三行
along@along-laptop:~/code/shell/sed$ sed '3d' datafile
along 04075021 1 90
xiaoming 04075022 1 92
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

sed ‘3,$d’ datafile(删除第三行到最后一行)
sed '/along/d' datafile(包含模式along的行都被删除,其余行打印)
sed -n '/along/d' datafile(删除包含模式along的行,此时显示内容为空)

3)s命令(替换)
along@along-laptop:~/code/shell/sed$ sed 's/ming/long/g' datafile
along 04075021 1 90
xiaolong 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinlong 0408098 2 jinlong 37
用long替换所有的ming。如果没有g那么将只替换每一行第一个ming。比如(注意观察最后一行):
along@along-laptop:~/code/shell/sed$ sed 's/ming/long/' datafile
along 04075021 1 90
xiaolong 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinlong 0408098 2 jinming 37

sed 's/[9]/&.5/g' datafile (在所有的9后边都加上一个.5)
比如:
along@along-laptop:~/code/shell/sed$ sed 's/9/&.5/g' datafile
along 04075021 1 9.50
xiaoming 04075022 1 9.52
xiaoguang 04075032 2 89.5
chang 04075036 2 79.5
hang 0407509.58 3 70
jinming 040809.58 2 jinming 37
当符号“&”和s一起用的时候,表示在找到的匹配串后边加上相应的串。

紧跟在s命令后边的字符就是查找串和替换串之间的分隔符。分隔符默认是正斜杠,但是可以改变。无论什么字符
只要紧跟这s就成了新的分隔符。
比如:
along@along-laptop:~/code/shell/sed$ sed -n 's#ming#along#gp' datafile
xiaoalong 04075022 1 92
jinalong 0408098 2 jinalong 37

4)定址
along@along-laptop:~/code/shell/sed$ sed -n '1,/ming/p' datafile
along 04075021 1 90
xiaoming 04075022 1 92
从第一行开始打印直到第一次出现ming

along@along-laptop:~/code/shell/sed$ sed -n '2,2p' datafile
xiaoming 04075022 1 92
只打印第二行的内容。


5)-e多重编辑选项。用于sed执行多个编辑命令时将前一个的编辑结果应用到后一个编辑命令上。
along@along-laptop:~/code/shell/sed$ sed -n -e 's/ming/long/' -e 's/long/mn/gp' datafile
amn 04075021 1 90
xiaomn 04075022 1 92
jinmn 0408098 2 jinming 37
这个例子没有任何作用,只是为了说明问题。
首先第一行原来是along,当执行第一条编辑命令时发现无法匹配,于是继续执行第二条编辑命令将long替换为mn。
第二行就不用再说了。
第三行,首先执行第一条编辑命令,发现没有 g 命令,于是就只是将第一个ming替换为long;然后执行第二条编辑命令
此时虽然有 g 这个命令,但是已经于事无补,因为当前行此时只有一个long。所以结果也就理所当然是这样了jinmn 0408098 2 jinming 37。

6)r读文件。sed使用该命令将一个文本文件中的内容加到当前文件的特定位置。
比如:
along@along-laptop:~/code/shell/sed$ cat file
---------Read File------------
along@along-laptop:~/code/shell/sed$ sed '/along/r file' datafile
along 04075021 1 90
---------Read File------------
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

7)w 写文件命令。
sed使用该命令将当前文件中的匹配行写入另外一个文件中。
sed -n ‘/along/w newfile’ datafile
将datafile中包含along的行全部写如newfile文件中。

8)a 追加命令。在当前行之后添加新文本。
比如:
along@along-laptop:~/code/shell/sed$ sed '/along/a/----student----' datafile
along 04075021 1 90
----student----
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

9)i 插入命令。在当前行之前插入新文本。
比如:
along@along-laptop:~/code/shell/sed$ sed '/along/i/----student----' datafile
----student----
along 04075021 1 90
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

10)c 修改命令。sed使用该命令将当前行修改成新文本。
比如:
along@along-laptop:~/code/shell/sed$ sed '/ming/c/----student----' datafile
along 04075021 1 90
----student----
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
----student----

11)n 命令。sed使用该命令获取输入文件的下一行进行处理。
比如:
along@along-laptop:~/code/shell/sed$ cat datafile
along 04075021 1 90
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

along@along-laptop:~/code/shell/sed$ sed '/along/{n;s/ming/long/;}' datafile
along 04075021 1 90
xiaolong 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37
将包含along的文本的下一行中的ming改为long。

12)y 命令。转换。字符按照一对一的方式从左到有进行转换。
sed '1,3y/abc/ABC/' datafile

13)q 命令。退出。
sed ‘5q’ datafile
显示完第5行时退出。

14)暂存和取用:h和g命令。
h:将模式空间的内容复制到暂存缓冲区,即一个特殊的临时缓冲区。暂存缓冲区的当前内容被清除。
H: 将换行符和模式空间的内容追加到暂存缓冲区中,即使暂存缓冲区为空,这个命令也追加换行符。当暂存缓冲区为空时拷贝到暂存缓冲区的内容前边要加上空行,
当暂存缓冲区不为空时,H这个命令就又不再加空行了。 
g:将暂存缓冲区中的内容复制到模式空间中,并将当前的内容清除。
G:将暂存缓冲区内容追加到模式空间。如果暂存缓冲区为空,则将换行符添加到模式空间。

along@along-laptop:~/code/shell/sed$ cat datafile
along 04075021 1 90
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

1》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{h;d;} ' -e '$g' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
xiaoguang 04075032 2 89
首先找到包含xiao的行,以覆盖的方式将其复制到暂存缓冲区,然后删除当前行,最后以覆盖的方式取出。

2》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{H;d;} ' -e '$g' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70

xiaoming 04075022 1 92
xiaoguang 04075032 2 89
找到包含xiao的行,以追加的方式将其复制到暂存缓冲区,然后删除当前行,最后以覆盖的方式取出加在文件末尾。

3》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{H;d;}' -e '${g;s/.//;}' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
比较3和2的不同。

4》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{h;d;}' -e '$G' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37
xiaoguang 04075032 2 89
找到包含xiao的行,以覆盖的方式将其复制到暂存缓冲区,然后删除当前行,最后以追加的方式取出。

5》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{H;d;}' -e '$G' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

xiaoming 04075022 1 92
xiaoguang 04075032 2 89
找到包含xiao的行,以追加的方式将其复制到暂存缓冲区,然后删除当前行,最后以追加的方式取出。

6》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{H;d}' -e '$G' datafile|sed -e '/^$/d'
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
比较5和6的区别。6是清除了空行。

7》现在有文件file:
first line
second line
third line

sed -e '/third/{h;d;}' -e '/first/{G;}'
第1行,第一条命令不匹配,输出第一行;接下来执行第二条命令匹配,所以从暂存空间中取出内容,此时为空所以输出空行。
第二行,第一条不匹配,输出第二行,接下来第二条不匹配
第3行,第一条匹配所以直接执行第一条命令,不输出。接下来执行第二条命令。
故结果:
along@along-laptop:~/code/shell/sed$ sed -e '/third/{h;d;}' -e '/first/{G;}' file
first line

second line


sed -e '/third/{h;d;}' -e '/second/{G;}' file
第一行:第一条命令不匹配,输出第一行;接下来执行第二条命令,不匹配。
第二行:第一条命令不匹配,输出第二行;接下来执行第二条命令,匹配所以从暂存空间中取出内容,此时为空,所以输出空行。
第三行:第一条匹配,不输出,直接删除,并存入暂存空间;第二条不匹配。
故结果:(此时second下面有一个空行)
along@along-laptop:~/code/shell/sed$ sed -e '/third/{h;d;}' -e '/second/{G;}' file
first line
second line

sed -e '/third/{h;d;}' -e '/third/{G;}' file
第一行:第一条命令不匹配,输出第一行;接下来执行第二条命令,不匹配。
第二行:第一条命令不匹配,输出第二行;接下来执行第二条命令,不匹配。
第三行:第一条匹配,不输出,存入暂存空间,并直接从模式空间删除;第二条此时模式空间没有了内容所以也就无法匹配了。
故结果:
along@along-laptop:~/code/shell/sed$ sed -e '/third/{h;d;}' -e '/third/{G;}' file
first line
second line

15)删除空行
现在有文件datafile
along@along-laptop:~/code/shell/sed$ cat datafile
along 04075021 1 90

xiaoming 04075022 1 92

xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37
现在想要删除中间的两个空行和每行前边的空格。其中第一个空行是用回车符造成的。第二个使用空格造成的。
如果使用sed '/^$/d' datafile 那么只能删除第一个空行。要想删除两个空行同时删除空格就要这样写:
sed -e '/^[ ]*$/d' -e 's/^[ ]*//' datafile


16)我有文件gr:
90
ad
a9
#8

执行下面这个sed语句:
along@along-laptop:~/code/shell/sed$ sed -n '/^[^0-9a-z]*[0-9]/{1,/}/p' gr
90
#8
这里说明 90 和我的正则表达式 ^[^0-9a-z]*[0-9]/{1,/} 是匹配的。

^[^0-9a-z]*[0-9]/{1,/} 匹配的是:非数字和小写字母出现0次或多次,中间是任意字符,然后再加上1-n个数字组成的字符串。
而 90这个字符串行首是9 符合行首为 0个非数字和小写字母开头,因此就匹配了。

注意:*是匹配前面的0次或多次。
*是匹配前面的0次或多次。所以要匹配不以数字和小写字母开头,中间任意个字符再加一个或多个数字结尾用正则表达式/^[^0-9a-z].*[0-9]/{1,/}/就可以了。

17.sed直接将修改结果保存到源文件中,需要使用-i参数。 
也就是:sed -i 's/along/good/' sedx
将修改结果保存到另外的文件中要用到重定向或者是w。
也就是:sed 's/good/along/ w newfile' oldfile (会在终端上打印修改后的内容)
或者:sed 's/good/along/' oldfile > newfile (不在终端上打印)
比如下面的例子:
1)直接修改原文件
along@along-laptop:~/code/shell$ cat sedx
good name is along~
along@along-laptop:~/code/shell$ sed -i 's/good/along/' sedx
along@along-laptop:~/code/shell$ cat sedx
along name is along~
2)将结果打印到另外一个文件中。
也就是:sed -i 's/along/good/' sedx
将修改结果保存到另外的文件中要用到重定向或者是w。
along@along-laptop:~/code/shell$ cat sedx
along name is along~
along@along-laptop:~/code/shell$ sed 's/along/good/ w out' sedx
good name is along~
along@along-laptop:~/code/shell$ cat out
good name is along~
along@along-laptop:~/code/shell$ sed 's/good/along/' sedx > out
along@along-laptop:~/code/shell$ cat out
along name is along~

总结:
h:将模式空间的内容复制到暂存缓冲区, 
即一个特殊的临时缓冲区。暂存缓冲区的当前内容被清除。
H: 将换行符和模式空间的内容追加到暂存缓冲区中,即使暂存缓冲区为空,这个命令也追加换行符。当
暂 存缓冲区为空时拷到暂存缓冲区的内容前边要加上空行,当暂存缓冲区不为空时,H这个命令就
又不再加空行了。 
g:将暂存缓冲区中的内容复制到模式空间中,并将当前的内容清除。
G:将暂存缓冲区内容追加到模式空间。如果暂存缓冲区为空,则将换行符添加到模式空间。

along@along-laptop:~/code/shell/sed$ echo "123" | sed 'h;G'
123
123 ;因为h清空了暂存缓冲区,而且h拷贝时不会加上回车所以这里没有空格。
along@along-laptop:~/code/shell/sed$ echo "123" | sed 'H;G'
123

123 ;H拷贝时暂存缓冲区为空时拷贝到暂存缓冲区的内容前边要加上空行,所以这里会出现一个空行。
along@along-laptop:~/code/shell/sed$ echo "123" | sed 'H;g'

123 ;这和上边的一样,H会加上一个回车,同时g会清空模式空间当前的内容
along@along-laptop:~/code/shell/sed$ echo "123" | sed 'h;g'
123 ;h清空了暂存缓冲区,且拷贝时不加回车,g清空了模式空间,所以这里只有一行。
along@along-laptop:~/code/shell/sed$ echo "123" | sed 'H;H;g'

123
123 ;当暂存缓冲区不为空时H就不再加回车了。所以这里只有一个空行。

http://sed.sourceforge.net/sed1line_zh-CN.html

-------------------------------------------------------------------------
SED单行脚本快速参考(Unix 流编辑器) 2005年12月29日

英文标题:USEFUL ONE-LINE SCRIPTS FOR SED (Unix stream editor)
原标题:HANDY ONE-LINERS FOR SED (Unix stream editor)

整理:Eric Pement - 电邮:pemente[at]northpark[dot]edu 版本5.5
译者:Joe Hong - 电邮:hq00e[at]126[dot]com

在以下地址可找到本文档的最新(英文)版本:
http://sed.sourceforge.net/sed1line.txt
http://www.pement.org/sed/sed1line.txt

其他语言版本:
中文 - 
http://sed.sourceforge.net/sed1line_zh-CN.html
捷克语 - http://sed.sourceforge.net/sed1line_cz.html
荷语 - http://sed.sourceforge.net/sed1line_nl.html
法语 - http://sed.sourceforge.net/sed1line_fr.html
德语 - http://sed.sourceforge.net/sed1line_de.html
<!-- 意大利语 - http://sed.sourceforge.net/sed1line_it.html-->
葡语 - http://sed.sourceforge.net/sed1line_pt-BR.html
<!-- 西班牙语 - http://sed.sourceforge.net/sed1line_es.html-->




1.Sed是一个非交互性文本流编辑器。sed与awk类似,执行时可以使用命令行;可以将
sed命令写入一个文件,然后调用sed;也可以将sed命令插入一个脚本文件并使脚本文件可执行。
一般情况下sed并不与初始化文件打交道,他操作的只是一个拷贝,如果要修改原文件那么就要用-i选项。

2.sed的工作过程:sed逐行处理输入文件,首先从输入文件读入一行到模式空间
也就是临时缓冲区,在该行上执行所有命令,将结果发送到指定的区域(stdout或指定的文件中)。当我们执行的是
一个sed脚本文件,那么我们就从输入文件中读入一行数据到模式空间,执行脚本文件中的所有命令,然后在继续读取输入
文件的下一行,并开始用sed脚本文件中的命令去处理文本。

3.sed定位文本的方法有两种:一种是行号,一种是正则表达式。

4.命令与选项:sed命令告诉sed如何处理由地址指定的各输入行。如果没有指定地址,sed就会处理所有的输入行。
sed的命令包括:
a/ :在当前行之后添加。追加。
c/ :用新文本替换当前行的文本。
d :删除当前行
i/ :在当前行之前插入文本
p :打印行
g :在行内进行全局替换
w :将行写入文件
s :用一个字符串替换另一个
命令还有很多,这里只列出了比较常用的几个。
sed的选项:
-e :允许多项编辑
-f :指定sed脚本文件名
-n :取消默认的输出

4.当没有出现语法错误时sed返回0。出现语法错误时返回非零。

5.
采用下面这个datafiel文件作为示例
along 04075021 1 90
xiaolong 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinlong 0408098 2 jinming 37

1)p命令
along@along-laptop:~/code/shell/sed$ sed '/along/p' datafile
along 04075021 1 90
along 04075021 1 90
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

这是将所有找到的匹配行都打印两遍

along@along-laptop:~/code/shell/sed$ sed -n '/xiao/p' datafile
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
当加上了-n选项时,只打印匹配行。
-n要和 p 配合使用

2)d命令(删除)从模式空间中删除并读入下一行

sed ‘3d’ datafile:删除第三行
along@along-laptop:~/code/shell/sed$ sed '3d' datafile
along 04075021 1 90
xiaoming 04075022 1 92
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

sed ‘3,$d’ datafile(删除第三行到最后一行)
sed '/along/d' datafile(包含模式along的行都被删除,其余行打印)
sed -n '/along/d' datafile(删除包含模式along的行,此时显示内容为空)

3)s命令(替换)
along@along-laptop:~/code/shell/sed$ sed 's/ming/long/g' datafile
along 04075021 1 90
xiaolong 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinlong 0408098 2 jinlong 37
用long替换所有的ming。如果没有g那么将只替换每一行第一个ming。比如(注意观察最后一行):
along@along-laptop:~/code/shell/sed$ sed 's/ming/long/' datafile
along 04075021 1 90
xiaolong 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinlong 0408098 2 jinming 37

sed 's/[9]/&.5/g' datafile (在所有的9后边都加上一个.5)
比如:
along@along-laptop:~/code/shell/sed$ sed 's/9/&.5/g' datafile
along 04075021 1 9.50
xiaoming 04075022 1 9.52
xiaoguang 04075032 2 89.5
chang 04075036 2 79.5
hang 0407509.58 3 70
jinming 040809.58 2 jinming 37
当符号“&”和s一起用的时候,表示在找到的匹配串后边加上相应的串。

紧跟在s命令后边的字符就是查找串和替换串之间的分隔符。分隔符默认是正斜杠,但是可以改变。无论什么字符
只要紧跟这s就成了新的分隔符。
比如:
along@along-laptop:~/code/shell/sed$ sed -n 's#ming#along#gp' datafile
xiaoalong 04075022 1 92
jinalong 0408098 2 jinalong 37

4)定址
along@along-laptop:~/code/shell/sed$ sed -n '1,/ming/p' datafile
along 04075021 1 90
xiaoming 04075022 1 92
从第一行开始打印直到第一次出现ming

along@along-laptop:~/code/shell/sed$ sed -n '2,2p' datafile
xiaoming 04075022 1 92
只打印第二行的内容。


5)-e多重编辑选项。用于sed执行多个编辑命令时将前一个的编辑结果应用到后一个编辑命令上。
along@along-laptop:~/code/shell/sed$ sed -n -e 's/ming/long/' -e 's/long/mn/gp' datafile
amn 04075021 1 90
xiaomn 04075022 1 92
jinmn 0408098 2 jinming 37
这个例子没有任何作用,只是为了说明问题。
首先第一行原来是along,当执行第一条编辑命令时发现无法匹配,于是继续执行第二条编辑命令将long替换为mn。
第二行就不用再说了。
第三行,首先执行第一条编辑命令,发现没有 g 命令,于是就只是将第一个ming替换为long;然后执行第二条编辑命令
此时虽然有 g 这个命令,但是已经于事无补,因为当前行此时只有一个long。所以结果也就理所当然是这样了jinmn 0408098 2 jinming 37。

6)r读文件。sed使用该命令将一个文本文件中的内容加到当前文件的特定位置。
比如:
along@along-laptop:~/code/shell/sed$ cat file
---------Read File------------
along@along-laptop:~/code/shell/sed$ sed '/along/r file' datafile
along 04075021 1 90
---------Read File------------
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

7)w 写文件命令。
sed使用该命令将当前文件中的匹配行写入另外一个文件中。
sed -n ‘/along/w newfile’ datafile
将datafile中包含along的行全部写如newfile文件中。

8)a 追加命令。在当前行之后添加新文本。
比如:
along@along-laptop:~/code/shell/sed$ sed '/along/a/----student----' datafile
along 04075021 1 90
----student----
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

9)i 插入命令。在当前行之前插入新文本。
比如:
along@along-laptop:~/code/shell/sed$ sed '/along/i/----student----' datafile
----student----
along 04075021 1 90
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

10)c 修改命令。sed使用该命令将当前行修改成新文本。
比如:
along@along-laptop:~/code/shell/sed$ sed '/ming/c/----student----' datafile
along 04075021 1 90
----student----
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
----student----

11)n 命令。sed使用该命令获取输入文件的下一行进行处理。
比如:
along@along-laptop:~/code/shell/sed$ cat datafile
along 04075021 1 90
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

along@along-laptop:~/code/shell/sed$ sed '/along/{n;s/ming/long/;}' datafile
along 04075021 1 90
xiaolong 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37
将包含along的文本的下一行中的ming改为long。

12)y 命令。转换。字符按照一对一的方式从左到有进行转换。
sed '1,3y/abc/ABC/' datafile

13)q 命令。退出。
sed ‘5q’ datafile
显示完第5行时退出。

14)暂存和取用:h和g命令。
h:将模式空间的内容复制到暂存缓冲区,即一个特殊的临时缓冲区。暂存缓冲区的当前内容被清除。
H: 将换行符和模式空间的内容追加到暂存缓冲区中,即使暂存缓冲区为空,这个命令也追加换行符。当暂存缓冲区为空时拷贝到暂存缓冲区的内容前边要加上空行,
当暂存缓冲区不为空时,H这个命令就又不再加空行了。 
g:将暂存缓冲区中的内容复制到模式空间中,并将当前的内容清除。
G:将暂存缓冲区内容追加到模式空间。如果暂存缓冲区为空,则将换行符添加到模式空间。

along@along-laptop:~/code/shell/sed$ cat datafile
along 04075021 1 90
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

1》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{h;d;} ' -e '$g' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
xiaoguang 04075032 2 89
首先找到包含xiao的行,以覆盖的方式将其复制到暂存缓冲区,然后删除当前行,最后以覆盖的方式取出。

2》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{H;d;} ' -e '$g' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70

xiaoming 04075022 1 92
xiaoguang 04075032 2 89
找到包含xiao的行,以追加的方式将其复制到暂存缓冲区,然后删除当前行,最后以覆盖的方式取出加在文件末尾。

3》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{H;d;}' -e '${g;s/.//;}' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
比较3和2的不同。

4》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{h;d;}' -e '$G' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37
xiaoguang 04075032 2 89
找到包含xiao的行,以覆盖的方式将其复制到暂存缓冲区,然后删除当前行,最后以追加的方式取出。

5》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{H;d;}' -e '$G' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

xiaoming 04075022 1 92
xiaoguang 04075032 2 89
找到包含xiao的行,以追加的方式将其复制到暂存缓冲区,然后删除当前行,最后以追加的方式取出。

6》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{H;d}' -e '$G' datafile|sed -e '/^$/d'
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
比较5和6的区别。6是清除了空行。

7》现在有文件file:
first line
second line
third line

sed -e '/third/{h;d;}' -e '/first/{G;}'
第1行,第一条命令不匹配,输出第一行;接下来执行第二条命令匹配,所以从暂存空间中取出内容,此时为空所以输出空行。
第二行,第一条不匹配,输出第二行,接下来第二条不匹配
第3行,第一条匹配所以直接执行第一条命令,不输出。接下来执行第二条命令。
故结果:
along@along-laptop:~/code/shell/sed$ sed -e '/third/{h;d;}' -e '/first/{G;}' file
first line

second line


sed -e '/third/{h;d;}' -e '/second/{G;}' file
第一行:第一条命令不匹配,输出第一行;接下来执行第二条命令,不匹配。
第二行:第一条命令不匹配,输出第二行;接下来执行第二条命令,匹配所以从暂存空间中取出内容,此时为空,所以输出空行。
第三行:第一条匹配,不输出,直接删除,并存入暂存空间;第二条不匹配。
故结果:(此时second下面有一个空行)
along@along-laptop:~/code/shell/sed$ sed -e '/third/{h;d;}' -e '/second/{G;}' file
first line
second line

sed -e '/third/{h;d;}' -e '/third/{G;}' file
第一行:第一条命令不匹配,输出第一行;接下来执行第二条命令,不匹配。
第二行:第一条命令不匹配,输出第二行;接下来执行第二条命令,不匹配。
第三行:第一条匹配,不输出,存入暂存空间,并直接从模式空间删除;第二条此时模式空间没有了内容所以也就无法匹配了。
故结果:
along@along-laptop:~/code/shell/sed$ sed -e '/third/{h;d;}' -e '/third/{G;}' file
first line
second line

15)删除空行
现在有文件datafile
along@along-laptop:~/code/shell/sed$ cat datafile
along 04075021 1 90

xiaoming 04075022 1 92

xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37
现在想要删除中间的两个空行和每行前边的空格。其中第一个空行是用回车符造成的。第二个使用空格造成的。
如果使用sed '/^$/d' datafile 那么只能删除第一个空行。要想删除两个空行同时删除空格就要这样写:
sed -e '/^[ ]*$/d' -e 's/^[ ]*//' datafile


16)我有文件gr:
90
ad
a9
#8

执行下面这个sed语句:
along@along-laptop:~/code/shell/sed$ sed -n '/^[^0-9a-z]*[0-9]/{1,/}/p' gr
90
#8
这里说明 90 和我的正则表达式 ^[^0-9a-z]*[0-9]/{1,/} 是匹配的。

^[^0-9a-z]*[0-9]/{1,/} 匹配的是:非数字和小写字母出现0次或多次,中间是任意字符,然后再加上1-n个数字组成的字符串。
而 90这个字符串行首是9 符合行首为 0个非数字和小写字母开头,因此就匹配了。

注意:*是匹配前面的0次或多次。
*是匹配前面的0次或多次。所以要匹配不以数字和小写字母开头,中间任意个字符再加一个或多个数字结尾用正则表达式/^[^0-9a-z].*[0-9]/{1,/}/就可以了。

17.sed直接将修改结果保存到源文件中,需要使用-i参数。 
也就是:sed -i 's/along/good/' sedx
将修改结果保存到另外的文件中要用到重定向或者是w。
也就是:sed 's/good/along/ w newfile' oldfile (会在终端上打印修改后的内容)
或者:sed 's/good/along/' oldfile > newfile (不在终端上打印)
比如下面的例子:
1)直接修改原文件
along@along-laptop:~/code/shell$ cat sedx
good name is along~
along@along-laptop:~/code/shell$ sed -i 's/good/along/' sedx
along@along-laptop:~/code/shell$ cat sedx
along name is along~
2)将结果打印到另外一个文件中。
也就是:sed -i 's/along/good/' sedx
将修改结果保存到另外的文件中要用到重定向或者是w。
along@along-laptop:~/code/shell$ cat sedx
along name is along~
along@along-laptop:~/code/shell$ sed 's/along/good/ w out' sedx
good name is along~
along@along-laptop:~/code/shell$ cat out
good name is along~
along@along-laptop:~/code/shell$ sed 's/good/along/' sedx > out
along@along-laptop:~/code/shell$ cat out
along name is along~

总结:
h:将模式空间的内容复制到暂存缓冲区, 
即一个特殊的临时缓冲区。暂存缓冲区的当前内容被清除。
H: 将换行符和模式空间的内容追加到暂存缓冲区中,即使暂存缓冲区为空,这个命令也追加换行符。当
暂 存缓冲区为空时拷到暂存缓冲区的内容前边要加上空行,当暂存缓冲区不为空时,H这个命令就
又不再加空行了。 
g:将暂存缓冲区中的内容复制到模式空间中,并将当前的内容清除。
G:将暂存缓冲区内容追加到模式空间。如果暂存缓冲区为空,则将换行符添加到模式空间。

along@along-laptop:~/code/shell/sed$ echo "123" | sed 'h;G'
123
123 ;因为h清空了暂存缓冲区,而且h拷贝时不会加上回车所以这里没有空格。
along@along-laptop:~/code/shell/sed$ echo "123" | sed 'H;G'
123

123 ;H拷贝时暂存缓冲区为空时拷贝到暂存缓冲区的内容前边要加上空行,所以这里会出现一个空行。
along@along-laptop:~/code/shell/sed$ echo "123" | sed 'H;g'

123 ;这和上边的一样,H会加上一个回车,同时g会清空模式空间当前的内容
along@along-laptop:~/code/shell/sed$ echo "123" | sed 'h;g'
123 ;h清空了暂存缓冲区,且拷贝时不加回车,g清空了模式空间,所以这里只有一行。
along@along-laptop:~/code/shell/sed$ echo "123" | sed 'H;H;g'

123
123 ;当暂存缓冲区不为空时H就不再加回车了。所以这里只有一个空行。

http://sed.sourceforge.net/sed1line_zh-CN.html

-------------------------------------------------------------------------
SED单行脚本快速参考(Unix 流编辑器) 2005年12月29日

英文标题:USEFUL ONE-LINE SCRIPTS FOR SED (Unix stream editor)
原标题:HANDY ONE-LINERS FOR SED (Unix stream editor)

整理:Eric Pement - 电邮:pemente[at]northpark[dot]edu 版本5.5
译者:Joe Hong - 电邮:hq00e[at]126[dot]com

在以下地址可找到本文档的最新(英文)版本:
http://sed.sourceforge.net/sed1line.txt
http://www.pement.org/sed/sed1line.txt

其他语言版本:
中文 - 
http://sed.sourceforge.net/sed1line_zh-CN.html
捷克语 - http://sed.sourceforge.net/sed1line_cz.html
荷语 - http://sed.sourceforge.net/sed1line_nl.html
法语 - http://sed.sourceforge.net/sed1line_fr.html
德语 - http://sed.sourceforge.net/sed1line_de.html
<!-- 意大利语 - http://sed.sourceforge.net/sed1line_it.html-->
葡语 - http://sed.sourceforge.net/sed1line_pt-BR.html
<!-- 西班牙语 - http://sed.sourceforge.net/sed1line_es.html-->


1.Sed是一个非交互性文本流编辑器。sed与awk类似,执行时可以使用命令行;可以将
sed命令写入一个文件,然后调用sed;也可以将sed命令插入一个脚本文件并使脚本文件可执行。
一般情况下sed并不与初始化文件打交道,他操作的只是一个拷贝,如果要修改原文件那么就要用-i选项。

2.sed的工作过程:sed逐行处理输入文件,首先从输入文件读入一行到模式空间
也就是临时缓冲区,在该行上执行所有命令,将结果发送到指定的区域(stdout或指定的文件中)。当我们执行的是
一个sed脚本文件,那么我们就从输入文件中读入一行数据到模式空间,执行脚本文件中的所有命令,然后在继续读取输入
文件的下一行,并开始用sed脚本文件中的命令去处理文本。

3.sed定位文本的方法有两种:一种是行号,一种是正则表达式。

4.命令与选项:sed命令告诉sed如何处理由地址指定的各输入行。如果没有指定地址,sed就会处理所有的输入行。
sed的命令包括:
a/ :在当前行之后添加。追加。
c/ :用新文本替换当前行的文本。
d :删除当前行
i/ :在当前行之前插入文本
p :打印行
g :在行内进行全局替换
w :将行写入文件
s :用一个字符串替换另一个
命令还有很多,这里只列出了比较常用的几个。
sed的选项:
-e :允许多项编辑
-f :指定sed脚本文件名
-n :取消默认的输出

4.当没有出现语法错误时sed返回0。出现语法错误时返回非零。

5.
采用下面这个datafiel文件作为示例
along 04075021 1 90
xiaolong 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinlong 0408098 2 jinming 37

1)p命令
along@along-laptop:~/code/shell/sed$ sed '/along/p' datafile
along 04075021 1 90
along 04075021 1 90
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

这是将所有找到的匹配行都打印两遍

along@along-laptop:~/code/shell/sed$ sed -n '/xiao/p' datafile
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
当加上了-n选项时,只打印匹配行。
-n要和 p 配合使用

2)d命令(删除)从模式空间中删除并读入下一行

sed ‘3d’ datafile:删除第三行
along@along-laptop:~/code/shell/sed$ sed '3d' datafile
along 04075021 1 90
xiaoming 04075022 1 92
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

sed ‘3,$d’ datafile(删除第三行到最后一行)
sed '/along/d' datafile(包含模式along的行都被删除,其余行打印)
sed -n '/along/d' datafile(删除包含模式along的行,此时显示内容为空)

3)s命令(替换)
along@along-laptop:~/code/shell/sed$ sed 's/ming/long/g' datafile
along 04075021 1 90
xiaolong 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinlong 0408098 2 jinlong 37
用long替换所有的ming。如果没有g那么将只替换每一行第一个ming。比如(注意观察最后一行):
along@along-laptop:~/code/shell/sed$ sed 's/ming/long/' datafile
along 04075021 1 90
xiaolong 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinlong 0408098 2 jinming 37

sed 's/[9]/&.5/g' datafile (在所有的9后边都加上一个.5)
比如:
along@along-laptop:~/code/shell/sed$ sed 's/9/&.5/g' datafile
along 04075021 1 9.50
xiaoming 04075022 1 9.52
xiaoguang 04075032 2 89.5
chang 04075036 2 79.5
hang 0407509.58 3 70
jinming 040809.58 2 jinming 37
当符号“&”和s一起用的时候,表示在找到的匹配串后边加上相应的串。

紧跟在s命令后边的字符就是查找串和替换串之间的分隔符。分隔符默认是正斜杠,但是可以改变。无论什么字符
只要紧跟这s就成了新的分隔符。
比如:
along@along-laptop:~/code/shell/sed$ sed -n 's#ming#along#gp' datafile
xiaoalong 04075022 1 92
jinalong 0408098 2 jinalong 37

4)定址
along@along-laptop:~/code/shell/sed$ sed -n '1,/ming/p' datafile
along 04075021 1 90
xiaoming 04075022 1 92
从第一行开始打印直到第一次出现ming

along@along-laptop:~/code/shell/sed$ sed -n '2,2p' datafile
xiaoming 04075022 1 92
只打印第二行的内容。


5)-e多重编辑选项。用于sed执行多个编辑命令时将前一个的编辑结果应用到后一个编辑命令上。
along@along-laptop:~/code/shell/sed$ sed -n -e 's/ming/long/' -e 's/long/mn/gp' datafile
amn 04075021 1 90
xiaomn 04075022 1 92
jinmn 0408098 2 jinming 37
这个例子没有任何作用,只是为了说明问题。
首先第一行原来是along,当执行第一条编辑命令时发现无法匹配,于是继续执行第二条编辑命令将long替换为mn。
第二行就不用再说了。
第三行,首先执行第一条编辑命令,发现没有 g 命令,于是就只是将第一个ming替换为long;然后执行第二条编辑命令
此时虽然有 g 这个命令,但是已经于事无补,因为当前行此时只有一个long。所以结果也就理所当然是这样了jinmn 0408098 2 jinming 37。

6)r读文件。sed使用该命令将一个文本文件中的内容加到当前文件的特定位置。
比如:
along@along-laptop:~/code/shell/sed$ cat file
---------Read File------------
along@along-laptop:~/code/shell/sed$ sed '/along/r file' datafile
along 04075021 1 90
---------Read File------------
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

7)w 写文件命令。
sed使用该命令将当前文件中的匹配行写入另外一个文件中。
sed -n ‘/along/w newfile’ datafile
将datafile中包含along的行全部写如newfile文件中。

8)a 追加命令。在当前行之后添加新文本。
比如:
along@along-laptop:~/code/shell/sed$ sed '/along/a/----student----' datafile
along 04075021 1 90
----student----
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

9)i 插入命令。在当前行之前插入新文本。
比如:
along@along-laptop:~/code/shell/sed$ sed '/along/i/----student----' datafile
----student----
along 04075021 1 90
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

10)c 修改命令。sed使用该命令将当前行修改成新文本。
比如:
along@along-laptop:~/code/shell/sed$ sed '/ming/c/----student----' datafile
along 04075021 1 90
----student----
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
----student----

11)n 命令。sed使用该命令获取输入文件的下一行进行处理。
比如:
along@along-laptop:~/code/shell/sed$ cat datafile
along 04075021 1 90
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

along@along-laptop:~/code/shell/sed$ sed '/along/{n;s/ming/long/;}' datafile
along 04075021 1 90
xiaolong 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37
将包含along的文本的下一行中的ming改为long。

12)y 命令。转换。字符按照一对一的方式从左到有进行转换。
sed '1,3y/abc/ABC/' datafile

13)q 命令。退出。
sed ‘5q’ datafile
显示完第5行时退出。

14)暂存和取用:h和g命令。
h:将模式空间的内容复制到暂存缓冲区,即一个特殊的临时缓冲区。暂存缓冲区的当前内容被清除。
H: 将换行符和模式空间的内容追加到暂存缓冲区中,即使暂存缓冲区为空,这个命令也追加换行符。当暂存缓冲区为空时拷贝到暂存缓冲区的内容前边要加上空行,
当暂存缓冲区不为空时,H这个命令就又不再加空行了。 
g:将暂存缓冲区中的内容复制到模式空间中,并将当前的内容清除。
G:将暂存缓冲区内容追加到模式空间。如果暂存缓冲区为空,则将换行符添加到模式空间。

along@along-laptop:~/code/shell/sed$ cat datafile
along 04075021 1 90
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

1》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{h;d;} ' -e '$g' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
xiaoguang 04075032 2 89
首先找到包含xiao的行,以覆盖的方式将其复制到暂存缓冲区,然后删除当前行,最后以覆盖的方式取出。

2》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{H;d;} ' -e '$g' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70

xiaoming 04075022 1 92
xiaoguang 04075032 2 89
找到包含xiao的行,以追加的方式将其复制到暂存缓冲区,然后删除当前行,最后以覆盖的方式取出加在文件末尾。

3》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{H;d;}' -e '${g;s/.//;}' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
比较3和2的不同。

4》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{h;d;}' -e '$G' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37
xiaoguang 04075032 2 89
找到包含xiao的行,以覆盖的方式将其复制到暂存缓冲区,然后删除当前行,最后以追加的方式取出。

5》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{H;d;}' -e '$G' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

xiaoming 04075022 1 92
xiaoguang 04075032 2 89
找到包含xiao的行,以追加的方式将其复制到暂存缓冲区,然后删除当前行,最后以追加的方式取出。

6》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{H;d}' -e '$G' datafile|sed -e '/^$/d'
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
比较5和6的区别。6是清除了空行。

7》现在有文件file:
first line
second line
third line

sed -e '/third/{h;d;}' -e '/first/{G;}'
第1行,第一条命令不匹配,输出第一行;接下来执行第二条命令匹配,所以从暂存空间中取出内容,此时为空所以输出空行。
第二行,第一条不匹配,输出第二行,接下来第二条不匹配
第3行,第一条匹配所以直接执行第一条命令,不输出。接下来执行第二条命令。
故结果:
along@along-laptop:~/code/shell/sed$ sed -e '/third/{h;d;}' -e '/first/{G;}' file
first line

second line


sed -e '/third/{h;d;}' -e '/second/{G;}' file
第一行:第一条命令不匹配,输出第一行;接下来执行第二条命令,不匹配。
第二行:第一条命令不匹配,输出第二行;接下来执行第二条命令,匹配所以从暂存空间中取出内容,此时为空,所以输出空行。
第三行:第一条匹配,不输出,直接删除,并存入暂存空间;第二条不匹配。
故结果:(此时second下面有一个空行)
along@along-laptop:~/code/shell/sed$ sed -e '/third/{h;d;}' -e '/second/{G;}' file
first line
second line

sed -e '/third/{h;d;}' -e '/third/{G;}' file
第一行:第一条命令不匹配,输出第一行;接下来执行第二条命令,不匹配。
第二行:第一条命令不匹配,输出第二行;接下来执行第二条命令,不匹配。
第三行:第一条匹配,不输出,存入暂存空间,并直接从模式空间删除;第二条此时模式空间没有了内容所以也就无法匹配了。
故结果:
along@along-laptop:~/code/shell/sed$ sed -e '/third/{h;d;}' -e '/third/{G;}' file
first line
second line

15)删除空行
现在有文件datafile
along@along-laptop:~/code/shell/sed$ cat datafile
along 04075021 1 90

xiaoming 04075022 1 92

xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37
现在想要删除中间的两个空行和每行前边的空格。其中第一个空行是用回车符造成的。第二个使用空格造成的。
如果使用sed '/^$/d' datafile 那么只能删除第一个空行。要想删除两个空行同时删除空格就要这样写:
sed -e '/^[ ]*$/d' -e 's/^[ ]*//' datafile


16)我有文件gr:
90
ad
a9
#8

执行下面这个sed语句:
along@along-laptop:~/code/shell/sed$ sed -n '/^[^0-9a-z]*[0-9]/{1,/}/p' gr
90
#8
这里说明 90 和我的正则表达式 ^[^0-9a-z]*[0-9]/{1,/} 是匹配的。

^[^0-9a-z]*[0-9]/{1,/} 匹配的是:非数字和小写字母出现0次或多次,中间是任意字符,然后再加上1-n个数字组成的字符串。
而 90这个字符串行首是9 符合行首为 0个非数字和小写字母开头,因此就匹配了。

注意:*是匹配前面的0次或多次。
*是匹配前面的0次或多次。所以要匹配不以数字和小写字母开头,中间任意个字符再加一个或多个数字结尾用正则表达式/^[^0-9a-z].*[0-9]/{1,/}/就可以了。

17.sed直接将修改结果保存到源文件中,需要使用-i参数。 
也就是:sed -i 's/along/good/' sedx
将修改结果保存到另外的文件中要用到重定向或者是w。
也就是:sed 's/good/along/ w newfile' oldfile (会在终端上打印修改后的内容)
或者:sed 's/good/along/' oldfile > newfile (不在终端上打印)
比如下面的例子:
1)直接修改原文件
along@along-laptop:~/code/shell$ cat sedx
good name is along~
along@along-laptop:~/code/shell$ sed -i 's/good/along/' sedx
along@along-laptop:~/code/shell$ cat sedx
along name is along~
2)将结果打印到另外一个文件中。
也就是:sed -i 's/along/good/' sedx
将修改结果保存到另外的文件中要用到重定向或者是w。
along@along-laptop:~/code/shell$ cat sedx
along name is along~
along@along-laptop:~/code/shell$ sed 's/along/good/ w out' sedx
good name is along~
along@along-laptop:~/code/shell$ cat out
good name is along~
along@along-laptop:~/code/shell$ sed 's/good/along/' sedx > out
along@along-laptop:~/code/shell$ cat out
along name is along~

总结:
h:将模式空间的内容复制到暂存缓冲区, 
即一个特殊的临时缓冲区。暂存缓冲区的当前内容被清除。
H: 将换行符和模式空间的内容追加到暂存缓冲区中,即使暂存缓冲区为空,这个命令也追加换行符。当
暂 存缓冲区为空时拷到暂存缓冲区的内容前边要加上空行,当暂存缓冲区不为空时,H这个命令就
又不再加空行了。 
g:将暂存缓冲区中的内容复制到模式空间中,并将当前的内容清除。
G:将暂存缓冲区内容追加到模式空间。如果暂存缓冲区为空,则将换行符添加到模式空间。

along@along-laptop:~/code/shell/sed$ echo "123" | sed 'h;G'
123
123 ;因为h清空了暂存缓冲区,而且h拷贝时不会加上回车所以这里没有空格。
along@along-laptop:~/code/shell/sed$ echo "123" | sed 'H;G'
123

123 ;H拷贝时暂存缓冲区为空时拷贝到暂存缓冲区的内容前边要加上空行,所以这里会出现一个空行。
along@along-laptop:~/code/shell/sed$ echo "123" | sed 'H;g'

123 ;这和上边的一样,H会加上一个回车,同时g会清空模式空间当前的内容
along@along-laptop:~/code/shell/sed$ echo "123" | sed 'h;g'
123 ;h清空了暂存缓冲区,且拷贝时不加回车,g清空了模式空间,所以这里只有一行。
along@along-laptop:~/code/shell/sed$ echo "123" | sed 'H;H;g'

123
123 ;当暂存缓冲区不为空时H就不再加回车了。所以这里只有一个空行。

http://sed.sourceforge.net/sed1line_zh-CN.html

-------------------------------------------------------------------------
SED单行脚本快速参考(Unix 流编辑器) 2005年12月29日

英文标题:USEFUL ONE-LINE SCRIPTS FOR SED (Unix stream editor)
原标题:HANDY ONE-LINERS FOR SED (Unix stream editor)

整理:Eric Pement - 电邮:pemente[at]northpark[dot]edu 版本5.5
译者:Joe Hong - 电邮:hq00e[at]126[dot]com

在以下地址可找到本文档的最新(英文)版本:
http://sed.sourceforge.net/sed1line.txt
http://www.pement.org/sed/sed1line.txt

其他语言版本:
中文 - 
http://sed.sourceforge.net/sed1line_zh-CN.html
捷克语 - http://sed.sourceforge.net/sed1line_cz.html
荷语 - http://sed.sourceforge.net/sed1line_nl.html
法语 - http://sed.sourceforge.net/sed1line_fr.html
德语 - http://sed.sourceforge.net/sed1line_de.html
<!-- 意大利语 - http://sed.sourceforge.net/sed1line_it.html-->
葡语 - http://sed.sourceforge.net/sed1line_pt-BR.html
<!-- 西班牙语 - http://sed.sourceforge.net/sed1line_es.html-->

1.Sed是一个非交互性文本流编辑器。sed与awk类似,执行时可以使用命令行;可以将
sed命令写入一个文件,然后调用sed;也可以将sed命令插入一个脚本文件并使脚本文件可执行。
一般情况下sed并不与初始化文件打交道,他操作的只是一个拷贝,如果要修改原文件那么就要用-i选项。

2.sed的工作过程:sed逐行处理输入文件,首先从输入文件读入一行到模式空间
也就是临时缓冲区,在该行上执行所有命令,将结果发送到指定的区域(stdout或指定的文件中)。当我们执行的是
一个sed脚本文件,那么我们就从输入文件中读入一行数据到模式空间,执行脚本文件中的所有命令,然后在继续读取输入
文件的下一行,并开始用sed脚本文件中的命令去处理文本。

3.sed定位文本的方法有两种:一种是行号,一种是正则表达式。

4.命令与选项:sed命令告诉sed如何处理由地址指定的各输入行。如果没有指定地址,sed就会处理所有的输入行。
sed的命令包括:
a/ :在当前行之后添加。追加。
c/ :用新文本替换当前行的文本。
d :删除当前行
i/ :在当前行之前插入文本
p :打印行
g :在行内进行全局替换
w :将行写入文件
s :用一个字符串替换另一个
命令还有很多,这里只列出了比较常用的几个。
sed的选项:
-e :允许多项编辑
-f :指定sed脚本文件名
-n :取消默认的输出

4.当没有出现语法错误时sed返回0。出现语法错误时返回非零。

5.
采用下面这个datafiel文件作为示例
along 04075021 1 90
xiaolong 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinlong 0408098 2 jinming 37

1)p命令
along@along-laptop:~/code/shell/sed$ sed '/along/p' datafile
along 04075021 1 90
along 04075021 1 90
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

这是将所有找到的匹配行都打印两遍

along@along-laptop:~/code/shell/sed$ sed -n '/xiao/p' datafile
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
当加上了-n选项时,只打印匹配行。
-n要和 p 配合使用

2)d命令(删除)从模式空间中删除并读入下一行

sed ‘3d’ datafile:删除第三行
along@along-laptop:~/code/shell/sed$ sed '3d' datafile
along 04075021 1 90
xiaoming 04075022 1 92
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

sed ‘3,$d’ datafile(删除第三行到最后一行)
sed '/along/d' datafile(包含模式along的行都被删除,其余行打印)
sed -n '/along/d' datafile(删除包含模式along的行,此时显示内容为空)

3)s命令(替换)
along@along-laptop:~/code/shell/sed$ sed 's/ming/long/g' datafile
along 04075021 1 90
xiaolong 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinlong 0408098 2 jinlong 37
用long替换所有的ming。如果没有g那么将只替换每一行第一个ming。比如(注意观察最后一行):
along@along-laptop:~/code/shell/sed$ sed 's/ming/long/' datafile
along 04075021 1 90
xiaolong 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinlong 0408098 2 jinming 37

sed 's/[9]/&.5/g' datafile (在所有的9后边都加上一个.5)
比如:
along@along-laptop:~/code/shell/sed$ sed 's/9/&.5/g' datafile
along 04075021 1 9.50
xiaoming 04075022 1 9.52
xiaoguang 04075032 2 89.5
chang 04075036 2 79.5
hang 0407509.58 3 70
jinming 040809.58 2 jinming 37
当符号“&”和s一起用的时候,表示在找到的匹配串后边加上相应的串。

紧跟在s命令后边的字符就是查找串和替换串之间的分隔符。分隔符默认是正斜杠,但是可以改变。无论什么字符
只要紧跟这s就成了新的分隔符。
比如:
along@along-laptop:~/code/shell/sed$ sed -n 's#ming#along#gp' datafile
xiaoalong 04075022 1 92
jinalong 0408098 2 jinalong 37

4)定址
along@along-laptop:~/code/shell/sed$ sed -n '1,/ming/p' datafile
along 04075021 1 90
xiaoming 04075022 1 92
从第一行开始打印直到第一次出现ming

along@along-laptop:~/code/shell/sed$ sed -n '2,2p' datafile
xiaoming 04075022 1 92
只打印第二行的内容。


5)-e多重编辑选项。用于sed执行多个编辑命令时将前一个的编辑结果应用到后一个编辑命令上。
along@along-laptop:~/code/shell/sed$ sed -n -e 's/ming/long/' -e 's/long/mn/gp' datafile
amn 04075021 1 90
xiaomn 04075022 1 92
jinmn 0408098 2 jinming 37
这个例子没有任何作用,只是为了说明问题。
首先第一行原来是along,当执行第一条编辑命令时发现无法匹配,于是继续执行第二条编辑命令将long替换为mn。
第二行就不用再说了。
第三行,首先执行第一条编辑命令,发现没有 g 命令,于是就只是将第一个ming替换为long;然后执行第二条编辑命令
此时虽然有 g 这个命令,但是已经于事无补,因为当前行此时只有一个long。所以结果也就理所当然是这样了jinmn 0408098 2 jinming 37。

6)r读文件。sed使用该命令将一个文本文件中的内容加到当前文件的特定位置。
比如:
along@along-laptop:~/code/shell/sed$ cat file
---------Read File------------
along@along-laptop:~/code/shell/sed$ sed '/along/r file' datafile
along 04075021 1 90
---------Read File------------
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

7)w 写文件命令。
sed使用该命令将当前文件中的匹配行写入另外一个文件中。
sed -n ‘/along/w newfile’ datafile
将datafile中包含along的行全部写如newfile文件中。

8)a 追加命令。在当前行之后添加新文本。
比如:
along@along-laptop:~/code/shell/sed$ sed '/along/a/----student----' datafile
along 04075021 1 90
----student----
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

9)i 插入命令。在当前行之前插入新文本。
比如:
along@along-laptop:~/code/shell/sed$ sed '/along/i/----student----' datafile
----student----
along 04075021 1 90
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

10)c 修改命令。sed使用该命令将当前行修改成新文本。
比如:
along@along-laptop:~/code/shell/sed$ sed '/ming/c/----student----' datafile
along 04075021 1 90
----student----
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
----student----

11)n 命令。sed使用该命令获取输入文件的下一行进行处理。
比如:
along@along-laptop:~/code/shell/sed$ cat datafile
along 04075021 1 90
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

along@along-laptop:~/code/shell/sed$ sed '/along/{n;s/ming/long/;}' datafile
along 04075021 1 90
xiaolong 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37
将包含along的文本的下一行中的ming改为long。

12)y 命令。转换。字符按照一对一的方式从左到有进行转换。
sed '1,3y/abc/ABC/' datafile

13)q 命令。退出。
sed ‘5q’ datafile
显示完第5行时退出。

14)暂存和取用:h和g命令。
h:将模式空间的内容复制到暂存缓冲区,即一个特殊的临时缓冲区。暂存缓冲区的当前内容被清除。
H: 将换行符和模式空间的内容追加到暂存缓冲区中,即使暂存缓冲区为空,这个命令也追加换行符。当暂存缓冲区为空时拷贝到暂存缓冲区的内容前边要加上空行,
当暂存缓冲区不为空时,H这个命令就又不再加空行了。 
g:将暂存缓冲区中的内容复制到模式空间中,并将当前的内容清除。
G:将暂存缓冲区内容追加到模式空间。如果暂存缓冲区为空,则将换行符添加到模式空间。

along@along-laptop:~/code/shell/sed$ cat datafile
along 04075021 1 90
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

1》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{h;d;} ' -e '$g' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
xiaoguang 04075032 2 89
首先找到包含xiao的行,以覆盖的方式将其复制到暂存缓冲区,然后删除当前行,最后以覆盖的方式取出。

2》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{H;d;} ' -e '$g' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70

xiaoming 04075022 1 92
xiaoguang 04075032 2 89
找到包含xiao的行,以追加的方式将其复制到暂存缓冲区,然后删除当前行,最后以覆盖的方式取出加在文件末尾。

3》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{H;d;}' -e '${g;s/.//;}' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
比较3和2的不同。

4》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{h;d;}' -e '$G' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37
xiaoguang 04075032 2 89
找到包含xiao的行,以覆盖的方式将其复制到暂存缓冲区,然后删除当前行,最后以追加的方式取出。

5》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{H;d;}' -e '$G' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

xiaoming 04075022 1 92
xiaoguang 04075032 2 89
找到包含xiao的行,以追加的方式将其复制到暂存缓冲区,然后删除当前行,最后以追加的方式取出。

6》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{H;d}' -e '$G' datafile|sed -e '/^$/d'
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
比较5和6的区别。6是清除了空行。

7》现在有文件file:
first line
second line
third line

sed -e '/third/{h;d;}' -e '/first/{G;}'
第1行,第一条命令不匹配,输出第一行;接下来执行第二条命令匹配,所以从暂存空间中取出内容,此时为空所以输出空行。
第二行,第一条不匹配,输出第二行,接下来第二条不匹配
第3行,第一条匹配所以直接执行第一条命令,不输出。接下来执行第二条命令。
故结果:
along@along-laptop:~/code/shell/sed$ sed -e '/third/{h;d;}' -e '/first/{G;}' file
first line

second line


sed -e '/third/{h;d;}' -e '/second/{G;}' file
第一行:第一条命令不匹配,输出第一行;接下来执行第二条命令,不匹配。
第二行:第一条命令不匹配,输出第二行;接下来执行第二条命令,匹配所以从暂存空间中取出内容,此时为空,所以输出空行。
第三行:第一条匹配,不输出,直接删除,并存入暂存空间;第二条不匹配。
故结果:(此时second下面有一个空行)
along@along-laptop:~/code/shell/sed$ sed -e '/third/{h;d;}' -e '/second/{G;}' file
first line
second line

sed -e '/third/{h;d;}' -e '/third/{G;}' file
第一行:第一条命令不匹配,输出第一行;接下来执行第二条命令,不匹配。
第二行:第一条命令不匹配,输出第二行;接下来执行第二条命令,不匹配。
第三行:第一条匹配,不输出,存入暂存空间,并直接从模式空间删除;第二条此时模式空间没有了内容所以也就无法匹配了。
故结果:
along@along-laptop:~/code/shell/sed$ sed -e '/third/{h;d;}' -e '/third/{G;}' file
first line
second line

15)删除空行
现在有文件datafile
along@along-laptop:~/code/shell/sed$ cat datafile
along 04075021 1 90

xiaoming 04075022 1 92

xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37
现在想要删除中间的两个空行和每行前边的空格。其中第一个空行是用回车符造成的。第二个使用空格造成的。
如果使用sed '/^$/d' datafile 那么只能删除第一个空行。要想删除两个空行同时删除空格就要这样写:
sed -e '/^[ ]*$/d' -e 's/^[ ]*//' datafile


16)我有文件gr:
90
ad
a9
#8

执行下面这个sed语句:
along@along-laptop:~/code/shell/sed$ sed -n '/^[^0-9a-z]*[0-9]/{1,/}/p' gr
90
#8
这里说明 90 和我的正则表达式 ^[^0-9a-z]*[0-9]/{1,/} 是匹配的。

^[^0-9a-z]*[0-9]/{1,/} 匹配的是:非数字和小写字母出现0次或多次,中间是任意字符,然后再加上1-n个数字组成的字符串。
而 90这个字符串行首是9 符合行首为 0个非数字和小写字母开头,因此就匹配了。

注意:*是匹配前面的0次或多次。
*是匹配前面的0次或多次。所以要匹配不以数字和小写字母开头,中间任意个字符再加一个或多个数字结尾用正则表达式/^[^0-9a-z].*[0-9]/{1,/}/就可以了。

17.sed直接将修改结果保存到源文件中,需要使用-i参数。 
也就是:sed -i 's/along/good/' sedx
将修改结果保存到另外的文件中要用到重定向或者是w。
也就是:sed 's/good/along/ w newfile' oldfile (会在终端上打印修改后的内容)
或者:sed 's/good/along/' oldfile > newfile (不在终端上打印)
比如下面的例子:
1)直接修改原文件
along@along-laptop:~/code/shell$ cat sedx
good name is along~
along@along-laptop:~/code/shell$ sed -i 's/good/along/' sedx
along@along-laptop:~/code/shell$ cat sedx
along name is along~
2)将结果打印到另外一个文件中。
也就是:sed -i 's/along/good/' sedx
将修改结果保存到另外的文件中要用到重定向或者是w。
along@along-laptop:~/code/shell$ cat sedx
along name is along~
along@along-laptop:~/code/shell$ sed 's/along/good/ w out' sedx
good name is along~
along@along-laptop:~/code/shell$ cat out
good name is along~
along@along-laptop:~/code/shell$ sed 's/good/along/' sedx > out
along@along-laptop:~/code/shell$ cat out
along name is along~

总结:
h:将模式空间的内容复制到暂存缓冲区, 
即一个特殊的临时缓冲区。暂存缓冲区的当前内容被清除。
H: 将换行符和模式空间的内容追加到暂存缓冲区中,即使暂存缓冲区为空,这个命令也追加换行符。当
暂 存缓冲区为空时拷到暂存缓冲区的内容前边要加上空行,当暂存缓冲区不为空时,H这个命令就
又不再加空行了。 
g:将暂存缓冲区中的内容复制到模式空间中,并将当前的内容清除。
G:将暂存缓冲区内容追加到模式空间。如果暂存缓冲区为空,则将换行符添加到模式空间。

along@along-laptop:~/code/shell/sed$ echo "123" | sed 'h;G'
123
123 ;因为h清空了暂存缓冲区,而且h拷贝时不会加上回车所以这里没有空格。
along@along-laptop:~/code/shell/sed$ echo "123" | sed 'H;G'
123

123 ;H拷贝时暂存缓冲区为空时拷贝到暂存缓冲区的内容前边要加上空行,所以这里会出现一个空行。
along@along-laptop:~/code/shell/sed$ echo "123" | sed 'H;g'

123 ;这和上边的一样,H会加上一个回车,同时g会清空模式空间当前的内容
along@along-laptop:~/code/shell/sed$ echo "123" | sed 'h;g'
123 ;h清空了暂存缓冲区,且拷贝时不加回车,g清空了模式空间,所以这里只有一行。
along@along-laptop:~/code/shell/sed$ echo "123" | sed 'H;H;g'

123
123 ;当暂存缓冲区不为空时H就不再加回车了。所以这里只有一个空行。

http://sed.sourceforge.net/sed1line_zh-CN.html

-------------------------------------------------------------------------
SED单行脚本快速参考(Unix 流编辑器) 2005年12月29日

英文标题:USEFUL ONE-LINE SCRIPTS FOR SED (Unix stream editor)
原标题:HANDY ONE-LINERS FOR SED (Unix stream editor)

整理:Eric Pement - 电邮:pemente[at]northpark[dot]edu 版本5.5
译者:Joe Hong - 电邮:hq00e[at]126[dot]com

在以下地址可找到本文档的最新(英文)版本:
http://sed.sourceforge.net/sed1line.txt
http://www.pement.org/sed/sed1line.txt

其他语言版本:
中文 - 
http://sed.sourceforge.net/sed1line_zh-CN.html
捷克语 - http://sed.sourceforge.net/sed1line_cz.html
荷语 - http://sed.sourceforge.net/sed1line_nl.html
法语 - http://sed.sourceforge.net/sed1line_fr.html
德语 - http://sed.sourceforge.net/sed1line_de.html
<!-- 意大利语 - http://sed.sourceforge.net/sed1line_it.html-->
葡语 - http://sed.sourceforge.net/sed1line_pt-BR.html
<!-- 西班牙语 - http://sed.sourceforge.net/sed1line_es.html-->

1.Sed是一个非交互性文本流编辑器。sed与awk类似,执行时可以使用命令行;可以将
sed命令写入一个文件,然后调用sed;也可以将sed命令插入一个脚本文件并使脚本文件可执行。
一般情况下sed并不与初始化文件打交道,他操作的只是一个拷贝,如果要修改原文件那么就要用-i选项。

2.sed的工作过程:sed逐行处理输入文件,首先从输入文件读入一行到模式空间
也就是临时缓冲区,在该行上执行所有命令,将结果发送到指定的区域(stdout或指定的文件中)。当我们执行的是
一个sed脚本文件,那么我们就从输入文件中读入一行数据到模式空间,执行脚本文件中的所有命令,然后在继续读取输入
文件的下一行,并开始用sed脚本文件中的命令去处理文本。

3.sed定位文本的方法有两种:一种是行号,一种是正则表达式。

4.命令与选项:sed命令告诉sed如何处理由地址指定的各输入行。如果没有指定地址,sed就会处理所有的输入行。
sed的命令包括:
a/ :在当前行之后添加。追加。
c/ :用新文本替换当前行的文本。
d :删除当前行
i/ :在当前行之前插入文本
p :打印行
g :在行内进行全局替换
w :将行写入文件
s :用一个字符串替换另一个
命令还有很多,这里只列出了比较常用的几个。
sed的选项:
-e :允许多项编辑
-f :指定sed脚本文件名
-n :取消默认的输出

4.当没有出现语法错误时sed返回0。出现语法错误时返回非零。

5.
采用下面这个datafiel文件作为示例
along 04075021 1 90
xiaolong 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinlong 0408098 2 jinming 37

1)p命令
along@along-laptop:~/code/shell/sed$ sed '/along/p' datafile
along 04075021 1 90
along 04075021 1 90
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

这是将所有找到的匹配行都打印两遍

along@along-laptop:~/code/shell/sed$ sed -n '/xiao/p' datafile
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
当加上了-n选项时,只打印匹配行。
-n要和 p 配合使用

2)d命令(删除)从模式空间中删除并读入下一行

sed ‘3d’ datafile:删除第三行
along@along-laptop:~/code/shell/sed$ sed '3d' datafile
along 04075021 1 90
xiaoming 04075022 1 92
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

sed ‘3,$d’ datafile(删除第三行到最后一行)
sed '/along/d' datafile(包含模式along的行都被删除,其余行打印)
sed -n '/along/d' datafile(删除包含模式along的行,此时显示内容为空)

3)s命令(替换)
along@along-laptop:~/code/shell/sed$ sed 's/ming/long/g' datafile
along 04075021 1 90
xiaolong 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinlong 0408098 2 jinlong 37
用long替换所有的ming。如果没有g那么将只替换每一行第一个ming。比如(注意观察最后一行):
along@along-laptop:~/code/shell/sed$ sed 's/ming/long/' datafile
along 04075021 1 90
xiaolong 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinlong 0408098 2 jinming 37

sed 's/[9]/&.5/g' datafile (在所有的9后边都加上一个.5)
比如:
along@along-laptop:~/code/shell/sed$ sed 's/9/&.5/g' datafile
along 04075021 1 9.50
xiaoming 04075022 1 9.52
xiaoguang 04075032 2 89.5
chang 04075036 2 79.5
hang 0407509.58 3 70
jinming 040809.58 2 jinming 37
当符号“&”和s一起用的时候,表示在找到的匹配串后边加上相应的串。

紧跟在s命令后边的字符就是查找串和替换串之间的分隔符。分隔符默认是正斜杠,但是可以改变。无论什么字符
只要紧跟这s就成了新的分隔符。
比如:
along@along-laptop:~/code/shell/sed$ sed -n 's#ming#along#gp' datafile
xiaoalong 04075022 1 92
jinalong 0408098 2 jinalong 37

4)定址
along@along-laptop:~/code/shell/sed$ sed -n '1,/ming/p' datafile
along 04075021 1 90
xiaoming 04075022 1 92
从第一行开始打印直到第一次出现ming

along@along-laptop:~/code/shell/sed$ sed -n '2,2p' datafile
xiaoming 04075022 1 92
只打印第二行的内容。


5)-e多重编辑选项。用于sed执行多个编辑命令时将前一个的编辑结果应用到后一个编辑命令上。
along@along-laptop:~/code/shell/sed$ sed -n -e 's/ming/long/' -e 's/long/mn/gp' datafile
amn 04075021 1 90
xiaomn 04075022 1 92
jinmn 0408098 2 jinming 37
这个例子没有任何作用,只是为了说明问题。
首先第一行原来是along,当执行第一条编辑命令时发现无法匹配,于是继续执行第二条编辑命令将long替换为mn。
第二行就不用再说了。
第三行,首先执行第一条编辑命令,发现没有 g 命令,于是就只是将第一个ming替换为long;然后执行第二条编辑命令
此时虽然有 g 这个命令,但是已经于事无补,因为当前行此时只有一个long。所以结果也就理所当然是这样了jinmn 0408098 2 jinming 37。

6)r读文件。sed使用该命令将一个文本文件中的内容加到当前文件的特定位置。
比如:
along@along-laptop:~/code/shell/sed$ cat file
---------Read File------------
along@along-laptop:~/code/shell/sed$ sed '/along/r file' datafile
along 04075021 1 90
---------Read File------------
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

7)w 写文件命令。
sed使用该命令将当前文件中的匹配行写入另外一个文件中。
sed -n ‘/along/w newfile’ datafile
将datafile中包含along的行全部写如newfile文件中。

8)a 追加命令。在当前行之后添加新文本。
比如:
along@along-laptop:~/code/shell/sed$ sed '/along/a/----student----' datafile
along 04075021 1 90
----student----
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

9)i 插入命令。在当前行之前插入新文本。
比如:
along@along-laptop:~/code/shell/sed$ sed '/along/i/----student----' datafile
----student----
along 04075021 1 90
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

10)c 修改命令。sed使用该命令将当前行修改成新文本。
比如:
along@along-laptop:~/code/shell/sed$ sed '/ming/c/----student----' datafile
along 04075021 1 90
----student----
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
----student----

11)n 命令。sed使用该命令获取输入文件的下一行进行处理。
比如:
along@along-laptop:~/code/shell/sed$ cat datafile
along 04075021 1 90
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

along@along-laptop:~/code/shell/sed$ sed '/along/{n;s/ming/long/;}' datafile
along 04075021 1 90
xiaolong 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37
将包含along的文本的下一行中的ming改为long。

12)y 命令。转换。字符按照一对一的方式从左到有进行转换。
sed '1,3y/abc/ABC/' datafile

13)q 命令。退出。
sed ‘5q’ datafile
显示完第5行时退出。

14)暂存和取用:h和g命令。
h:将模式空间的内容复制到暂存缓冲区,即一个特殊的临时缓冲区。暂存缓冲区的当前内容被清除。
H: 将换行符和模式空间的内容追加到暂存缓冲区中,即使暂存缓冲区为空,这个命令也追加换行符。当暂存缓冲区为空时拷贝到暂存缓冲区的内容前边要加上空行,
当暂存缓冲区不为空时,H这个命令就又不再加空行了。 
g:将暂存缓冲区中的内容复制到模式空间中,并将当前的内容清除。
G:将暂存缓冲区内容追加到模式空间。如果暂存缓冲区为空,则将换行符添加到模式空间。

along@along-laptop:~/code/shell/sed$ cat datafile
along 04075021 1 90
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

1》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{h;d;} ' -e '$g' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
xiaoguang 04075032 2 89
首先找到包含xiao的行,以覆盖的方式将其复制到暂存缓冲区,然后删除当前行,最后以覆盖的方式取出。

2》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{H;d;} ' -e '$g' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70

xiaoming 04075022 1 92
xiaoguang 04075032 2 89
找到包含xiao的行,以追加的方式将其复制到暂存缓冲区,然后删除当前行,最后以覆盖的方式取出加在文件末尾。

3》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{H;d;}' -e '${g;s/.//;}' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
比较3和2的不同。

4》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{h;d;}' -e '$G' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37
xiaoguang 04075032 2 89
找到包含xiao的行,以覆盖的方式将其复制到暂存缓冲区,然后删除当前行,最后以追加的方式取出。

5》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{H;d;}' -e '$G' datafile
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37

xiaoming 04075022 1 92
xiaoguang 04075032 2 89
找到包含xiao的行,以追加的方式将其复制到暂存缓冲区,然后删除当前行,最后以追加的方式取出。

6》along@along-laptop:~/code/shell/sed$ sed -e '/xiao/{H;d}' -e '$G' datafile|sed -e '/^$/d'
along 04075021 1 90
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37
xiaoming 04075022 1 92
xiaoguang 04075032 2 89
比较5和6的区别。6是清除了空行。

7》现在有文件file:
first line
second line
third line

sed -e '/third/{h;d;}' -e '/first/{G;}'
第1行,第一条命令不匹配,输出第一行;接下来执行第二条命令匹配,所以从暂存空间中取出内容,此时为空所以输出空行。
第二行,第一条不匹配,输出第二行,接下来第二条不匹配
第3行,第一条匹配所以直接执行第一条命令,不输出。接下来执行第二条命令。
故结果:
along@along-laptop:~/code/shell/sed$ sed -e '/third/{h;d;}' -e '/first/{G;}' file
first line

second line


sed -e '/third/{h;d;}' -e '/second/{G;}' file
第一行:第一条命令不匹配,输出第一行;接下来执行第二条命令,不匹配。
第二行:第一条命令不匹配,输出第二行;接下来执行第二条命令,匹配所以从暂存空间中取出内容,此时为空,所以输出空行。
第三行:第一条匹配,不输出,直接删除,并存入暂存空间;第二条不匹配。
故结果:(此时second下面有一个空行)
along@along-laptop:~/code/shell/sed$ sed -e '/third/{h;d;}' -e '/second/{G;}' file
first line
second line

sed -e '/third/{h;d;}' -e '/third/{G;}' file
第一行:第一条命令不匹配,输出第一行;接下来执行第二条命令,不匹配。
第二行:第一条命令不匹配,输出第二行;接下来执行第二条命令,不匹配。
第三行:第一条匹配,不输出,存入暂存空间,并直接从模式空间删除;第二条此时模式空间没有了内容所以也就无法匹配了。
故结果:
along@along-laptop:~/code/shell/sed$ sed -e '/third/{h;d;}' -e '/third/{G;}' file
first line
second line

15)删除空行
现在有文件datafile
along@along-laptop:~/code/shell/sed$ cat datafile
along 04075021 1 90

xiaoming 04075022 1 92

xiaoguang 04075032 2 89
chang 04075036 2 79
hang 04075098 3 70
jinming 0408098 2 jinming 37
现在想要删除中间的两个空行和每行前边的空格。其中第一个空行是用回车符造成的。第二个使用空格造成的。
如果使用sed '/^$/d' datafile 那么只能删除第一个空行。要想删除两个空行同时删除空格就要这样写:
sed -e '/^[ ]*$/d' -e 's/^[ ]*//' datafile


16)我有文件gr:
90
ad
a9
#8

执行下面这个sed语句:
along@along-laptop:~/code/shell/sed$ sed -n '/^[^0-9a-z]*[0-9]/{1,/}/p' gr
90
#8
这里说明 90 和我的正则表达式 ^[^0-9a-z]*[0-9]/{1,/} 是匹配的。

^[^0-9a-z]*[0-9]/{1,/} 匹配的是:非数字和小写字母出现0次或多次,中间是任意字符,然后再加上1-n个数字组成的字符串。
而 90这个字符串行首是9 符合行首为 0个非数字和小写字母开头,因此就匹配了。

注意:*是匹配前面的0次或多次。
*是匹配前面的0次或多次。所以要匹配不以数字和小写字母开头,中间任意个字符再加一个或多个数字结尾用正则表达式/^[^0-9a-z].*[0-9]/{1,/}/就可以了。

17.sed直接将修改结果保存到源文件中,需要使用-i参数。 
也就是:sed -i 's/along/good/' sedx
将修改结果保存到另外的文件中要用到重定向或者是w。
也就是:sed 's/good/along/ w newfile' oldfile (会在终端上打印修改后的内容)
或者:sed 's/good/along/' oldfile > newfile (不在终端上打印)
比如下面的例子:
1)直接修改原文件
along@along-laptop:~/code/shell$ cat sedx
good name is along~
along@along-laptop:~/code/shell$ sed -i 's/good/along/' sedx
along@along-laptop:~/code/shell$ cat sedx
along name is along~
2)将结果打印到另外一个文件中。
也就是:sed -i 's/along/good/' sedx
将修改结果保存到另外的文件中要用到重定向或者是w。
along@along-laptop:~/code/shell$ cat sedx
along name is along~
along@along-laptop:~/code/shell$ sed 's/along/good/ w out' sedx
good name is along~
along@along-laptop:~/code/shell$ cat out
good name is along~
along@along-laptop:~/code/shell$ sed 's/good/along/' sedx > out
along@along-laptop:~/code/shell$ cat out
along name is along~

总结:
h:将模式空间的内容复制到暂存缓冲区, 
即一个特殊的临时缓冲区。暂存缓冲区的当前内容被清除。
H: 将换行符和模式空间的内容追加到暂存缓冲区中,即使暂存缓冲区为空,这个命令也追加换行符。当
暂 存缓冲区为空时拷到暂存缓冲区的内容前边要加上空行,当暂存缓冲区不为空时,H这个命令就
又不再加空行了。 
g:将暂存缓冲区中的内容复制到模式空间中,并将当前的内容清除。
G:将暂存缓冲区内容追加到模式空间。如果暂存缓冲区为空,则将换行符添加到模式空间。

along@along-laptop:~/code/shell/sed$ echo "123" | sed 'h;G'
123
123 ;因为h清空了暂存缓冲区,而且h拷贝时不会加上回车所以这里没有空格。
along@along-laptop:~/code/shell/sed$ echo "123" | sed 'H;G'
123

123 ;H拷贝时暂存缓冲区为空时拷贝到暂存缓冲区的内容前边要加上空行,所以这里会出现一个空行。
along@along-laptop:~/code/shell/sed$ echo "123" | sed 'H;g'

123 ;这和上边的一样,H会加上一个回车,同时g会清空模式空间当前的内容
along@along-laptop:~/code/shell/sed$ echo "123" | sed 'h;g'
123 ;h清空了暂存缓冲区,且拷贝时不加回车,g清空了模式空间,所以这里只有一行。
along@along-laptop:~/code/shell/sed$ echo "123" | sed 'H;H;g'

123
123 ;当暂存缓冲区不为空时H就不再加回车了。所以这里只有一个空行。

http://sed.sourceforge.net/sed1line_zh-CN.html

-------------------------------------------------------------------------
SED单行脚本快速参考(Unix 流编辑器) 2005年12月29日

英文标题:USEFUL ONE-LINE SCRIPTS FOR SED (Unix stream editor)
原标题:HANDY ONE-LINERS FOR SED (Unix stream editor)

整理:Eric Pement - 电邮:pemente[at]northpark[dot]edu 版本5.5
译者:Joe Hong - 电邮:hq00e[at]126[dot]com

在以下地址可找到本文档的最新(英文)版本:
http://sed.sourceforge.net/sed1line.txt
http://www.pement.org/sed/sed1line.txt

其他语言版本:
中文 - 
http://sed.sourceforge.net/sed1line_zh-CN.html
捷克语 - http://sed.sourceforge.net/sed1line_cz.html
荷语 - http://sed.sourceforge.net/sed1line_nl.html
法语 - http://sed.sourceforge.net/sed1line_fr.html
德语 - http://sed.sourceforge.net/sed1line_de.html
<!-- 意大利语 - http://sed.sourceforge.net/sed1line_it.html-->
葡语 - http://sed.sourceforge.net/sed1line_pt-BR.html
<!-- 西班牙语 - http://sed.sourceforge.net/sed1line_es.html-->

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值