1,简介
Sed是一种在线编辑器(stream editor),它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。
2,sed工作原理
Pattern space和Hold space即模式空间和保留空间(也可以称之为缓冲区),保留空间的初始为空,我们可以认为是一个空行。
4 个空间 :input stream, pattern buffer, output stream 和 hold buffer
基本操作过程是 :
(1). 将 input stream 的当前行放入 pattern buffer, 然后 input stream 的指针指向下一行 ;
(2). 对 pattern buffer 中的行进行处理 ;
(3). 将 2 的处理结果放入 output stream. 然后循环这个过程 .
3,详解
(1)常用参数介绍
-n 取消默认输出,只有经过sed处理过的行才显示出来,其他不显示。 -e 直接在命令行模式上进行sed的操作。是默认选项,不用写。 -f 将sed的操作写在一个文件里,用的时候 -f filename 就可以按照内容进行sed操作了。 -r 使之支持扩展正则表达式 -i 直接对文件进行编辑
(2)常用函数参数介绍(一)
函数参数 功能
a\ 在当前行后添加一行或多行
b 无条件跳转到标签label,如果label没有指定,跳转到命令的结尾
c\ 用新文本修改(替换)当前行的文本
d 删除行
D 删除 模式空间 内第一个 newline 字母 \ 前的资料
g 取出缓冲区的内容,覆盖模式空间的内容
G 取出缓冲区的内容,追加到模式空间
h 拷贝资料从 模式空间 至 保留空间 。
H 添加资料从 模式空间 至 保留空间 。
i\ 插入添加使用者输入的资料行。
(3)常用函数参数介绍(二)
函数参数 功能
l 列出非打印字符
n 读入下一行,并从下条命令对其进行处理
N 添加下一笔资料到模式空间。
P(小写) 打印行
P(大写) 打印出模式空间 内第一个newline 字母\ 前的数据。
q 结束或退出sed
r 从文件中读取输入行
s 用一串字符替换一串字符
t 如果最后一次输入的最后一个 s/// 子命令执行成功,跳转到标签label,如果label没有指定,跳转到命令的结尾
w 将行写入文本
(3)常用函数参数介绍(三)
函数参数 功能
X 交换缓冲区和模式空间的内容
y 将字符转换成另一字符(不能对正则表达式使用y)
! 不执行函数参数
= 打印出文本行数
{} 集合有相同位址参数的集合
# 建立批注
: Lable标签
(4)元字符集
^ 锚定行的开始 如:/^sed/匹配所有以sed开头的行。
$ 锚定行的结尾 如:/sed$/匹配所有以sed结尾的行。
. 匹配一个非换行符的字符 如:/s.d/匹配s后接一个任意字符,然后是d。
* 匹配零或多个字符 如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行
[] 匹配一个指定范围内的字符,如/[Ss]ed/匹配sed和Sed。
[^] 匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行。
.\(..\) 保存匹配的字符,如s/\(love\)able/\1rs,loveable被替换成lovers。
& 保存搜索字符用来替换其他字符,如s/love/**&**/,love这成**love**。
\< 锚定单词的开始,如:/\<love/匹配包含以love开头的单词的行
\> 锚定单词的结束,如/love\>/匹配包含以love结尾的单词的行。
\{m\} 重复字符x,m次,如:/0\{5\}/匹配包含5个o的行。
\{m,\} 重复字符x,至少m次,如:/o\{5,\}/匹配至少有5个o的行。
\{m,n\} 重复字符x,至少m次,不多于n次,如:/o\{5,10\}/匹配5--10个o的行。
4基本命令
:s
1.1 基本用法
e.g. sed 's/day/night/' file
该例子将文件 file 中的每一行第一次出现的 day 替换成 night
s " 替换 " 命令
/../../ 分割符
day 搜索字符串
night 替换字符串
sed 's/day/night/'<file1>file把结果输出到file里。
其实 , 分割符 "/" 可以用别的符号代替 , 比如 ",", "|" 等 .
e.g. sed 's/\/usr\/local\/bin/\/common\/bin/'file
等价于 sed 's_/usr/local/bin_/common/bin_' file
显然 , 此时用 "_" 作分割符比 "/" 好得多 .
1.2 用 & 表示匹配的字符串
有时可能会想在匹配到的字符串周围或附近加上一些字符 .
e.g. sed 's/abc/(abc)/' file
该例子在找到的 abc 前后加上括号 .
该例子还可以写成 sed 's/abc/(&)/' file
下面是更复杂的例子 :
sed 's/[a-z]*/(&)/' file
sed 's/[0-9]*/& &/' file
1.3 用 \1, \2, ..., \9 来表示匹配的字符串
e.g. sed 's/\([a-z]*\)[0-9]*/\1/' file
本例中 \1 就是指前面的 \([a-z]*\)
sed 's/\([a-z]*\) \([0-9]*\)/\2 \1/'file
本例中 \2 和 \1 分别代表前面的 \([0-9]*\) 和 \([a-z]*\)
\1, \2, ..., \9 也可以出现在搜索字符串中
e.g. sed 's/\([a-z]*\) \1/\1/' file
本例可以去除重复的由字母组成的词
1.4 " 替换 " 选项
1.4.1 /g 替换所有的
sed 默认只替换搜索字符串的第一次出现 , 利用 /g 可以替换搜索字符串所有
出现的地方 . 例如 ,
sed 's/\([^ ]*\)/(&)/g' file
1.4.2 用 /1, /2, ... 来表明替换哪一次出现
e.g. sed 's/[^ ]*//2' file
可以从 /1 用到 /512
1.4.3 /p print 选项
当 sed 命令有 -n 选项时 , 该命令没用输出 .
-n 配合 /p 选项后 , 如果该行确实发生了替换 , 则输出该行 , 否则不输出 .
1.4.4 /w filename 写到文件 filename 中
e.g. sed 's/\([0-9]*\) \([a-z]*\)/\2/w file1' file
该例子把输出放入文件 file1 中
1.5 替换和插入换行符号
替换 (echo a;echo x;echo y) | sed '/x$/ {
N
s:x\n:x:
}'
插入
(echo a;echo x;echo y) | sed 's:x:X\
:'
2. 只对特定行的处理
2.1 通过行号限定
sed '3 s/[0-9][0-9]*//' file 只处理第 3 行
sed '1,100 s/A/a/' file 只处理 1 到 100 行
sed '101,$ s/A/a/' file
sed '101,$ !s/A/a/' file 这里 ! 表示只对 1 到 100 行进行替换 ,! 的作用 是取反
2.2 通过正规表达式限定
sed '/start/,/stop/ s/#.*//' file
本例中 ,sed 先找到有 start 的行作为开始 , 找到最近的有 stop 的行作为结束 , 对之
间的行进行操作 .
重复上述过程 , 直到文件结束
下面这个例子是行号和正规表达式配合来限定
sed '1,/start/ s/#.*//' file 对第 1 行到含有 start 的行进行处理
3. 其他的简单命令
3.1 删除命令 d
sed '11,$ d' file 删除从 11 行到文件末尾
sed '/^#/ d' file 删除所有以 # 开始的行
3.2 print 命令 p ( 注意 与 s 命令的 /p 选项的区别 )
sed 'p' file 每一行将会被输出两次
sed -n 'p' file 每一行将会输出一次 (-n 屏蔽掉一次 )
sed '/^$/ p' file 只对空行输出两次 , 其他只输出一次
sed -n '1,10 p' file 输出前 10 行
sed -n '/match/ p' file 输出含有 match 的行
3.3 quit 命令 q
sed '11 q'file 输出前 10 行 ( 在第 11 行退出 )
注意 :q 命令不能接收多行 , 例如
sed '2,5 q'file 是不正确的
3.4 写入文件命令 w filename( 注意与 s 命令的 /w 选项的区别 )
把某些行写入文件 filename
sed -n '/^[0-9]*[02468]/ w even' file 将以偶数开始的行写入文件 even
3.5 输出行号命令 =
sed -n '/PATTERN/ =' file 遇到含有 PATTERN 的行时 , 同时输出行号
3.6 追加 , 改变 , 插入新行
追加命令 a
#!/bin/sh
sed '
/WORD/ a\
Add this line after every line with WORD
'
改变命令 c
#!/bin/sh
sed '
/WORD/ c\
Replace the current line with the line
'
插入命令 i
#!/bin/sh
sed '
/WORD/ i\
Add this line before every line with WORD
'
3.7 变换命令 y
sed 'y/abcdef/ABCDEF/' file 该例将字符 abcdef 分别变成大写
3.8 将本行的控制符也显示出来的命令 l
sed '1,10 l' file
3.9 d 命令和 D 命令
d 命令删除 pattern buffer 中的内容进入下一次操作循环
D 命令删除 pattern buffer 中第一个换行符之前的内容进入下一次操作循环 , 如
果 pattern buffer 中还有内容 , 则不用从 input stream 中读入
3.10 p 命令和 P 命令
p 命令输出 pattern buffer 中的内容
P 命令输出 pattern buffer 中第一个换行符之前的内容
3.11 n 命令和 N 命令
n 命令把下一行读入 pattern buffer 中 ( 如果没用 -n 选项 , 将原来行输出 )
N 命令把下一行追加到 pattern buffer 中
3.12 流程控制命令
b label 命令 : 在指定行跳到 label
t label 命令 : 如果在某行发生了替换 , 跳到 label
T label 命令 : 如果在某行没有发生了替换 , 跳到 label
4. 调用 sed 时的参数
4.1 -e script 执行 script 这个脚本
e.g. sed -e 's/a/A/' -e 's/b/B/' file
对每一行分别执行 's/a/A/' 和 's/b/B/'
4.2 -n 禁止输出
这里的 -n 与前面的 /p 配合 , 可以只输出被修改了的行 .
4.3 -f scriptname 把 scriptname 文件中的 sed 命令加入本次 sed 的调用中
e.g. sed -f sedscript file
sedscript 的内容可能是这样的 :
# sed comment - This script changes lower case vowels to upper case
s/a/A/g
s/e/E/g
s/i/I/g
s/o/O/g
s/u/U/g
5. Hold Buffer
x 命令 : 将 pattern buffer 放入 hold buffer, 而将 hold buffer 的内容输出 ,pattern
buffer 的内容变成下一行
h 命令 : 将 pattern buffer 放入 hold buffer, 并将 pattern buffer 的内容输出 ,
pattern buffer 的内容变成下一行
H 命令 : 将 pattern buffer 追加到 hold buffer
g 和 G 命令 :g 用 hold buffer 的内容替换 pattern buffer 的内容 , 而 G 将 hold buffer 内
容追加到 pattern buffer
5,实战
sed ‘/2/a\this is after second line’ s1 在第二行后加入一段文字
sed ‘2i\this is befor second line’ s1 在第二行前加入一段文字
sed ‘2c\this is second line’ s1 把第二行内容改为。
sed ‘/AA/s/$/ YES/;t;s/$/ NO/’ s2 在AA后加入YES,其他后面加入NO
sed ‘/AA/ba;s/$/ NO/;t;:a;s/$/ YES/’ s2 等同上边
sed ‘/AA/!s/$/ NO/;t;s/$/ YES/’ s2 等同上边
sed ‘/AA/n;s/$/ NO/’ s2 在除AA的行后加入NO
sed -n ‘$p’ s1 打印第一行
sed ‘G;G’ s1 在每行后增加两行空行
sed -i ‘/AA/s//insert/’ s2 修改文件,把AA替换成insert
sed -e ‘s/1/111/’ -e ‘s/3/a/g’ s1 把1替换成111,把全行中的3替换成a
sed ‘/AA/s//aa/;q’ s2 把第一个AA替换成aa,然后退出
sed ‘y/BC/23/’ s2 把B替换成2,把C替换成3
sed -n ‘/AA/=’ s2 打印包含AA的行号
sed ‘/AA/{s/^/1/;s/$/2/}’ s2 包含AA的行,行首加1,行尾加2
1.嵌套与多重嵌套
sed '/book/,/qq/{s/hao/HAO/}' 5
sed '/book/,/qq/{/nihao/,/dajia/{s/hao/HAO/}}' 5
2.给匹配行去重
sed '/AA/{N;/AA/D}' 1
sed '/AA/{2,$d}' 1
3.高级替换
sed 's/car/red&/' s3
sed 's/\(my\)\(test\)\(car\)/\2\1\3/' s3
4.替换一行中的第N个匹配字符
sed 's/AA/qq/2' 11
替换一行中的全部匹配字符
Sed ‘s/AA/qq/g’ 115.打印文件中的奇数行 sed ‘n;d’ s1
sed 'x;$!N;x' s1
sed -n 'p;n' s1
sed -n 'P;N' s1
6. 打印文件中的偶数行
sed -n 'n;p' s1
sed '1d;n;d;' s1
常见sed等价命令
basename sed 's/\(.*\)\/\([^/]*\)/\2/' or sed 's,.*/,,'
cat sed '' or sed -n '1,$p' or sed '1,$!d'
cat -s sed '/./,/^$/!d'
cat -n sed '=' | sed 'N;s/\n/\t/;s/^/ &/' or sed '=' | sed '$!N;s/\n/ /'
cat -E sed 's/$/\$/'
cat -t sed 's/\t/^I/g'
cut -c n sed 's/\(.\)\{n\}.*/\1/' or sed 's/^.\{(n-1)\}//g;s/\(.\)\(.*\)/\1/g'
cut -c x-y sed 's/\(^.\{y\}\)\(.*\)/\1/g;s/^.\{(x-1)\}//'
cut -d| -f6 sed 's/\(\([^|]*\)\|\)\{6\}.*/\2/'
cp file1 file2 sed 'w file2' file1
expand -t 1 sed 's/\t/ /g'
dirname sed 's/\(.*\)\/\([^/]*\)/\1/' or sed 's,[^/]*$,,'
grep patten sed -n '/patten/p' or sed '/patten/!d'
grep -v patten sed -n '/patten/!p' or sed '/pateen/d'
grep -n patten sed -n '/patten/{=;p}'| sed 'N;s/\n/:/'head sed -n '1,10p'
head -1 sed -n '1p' or sed 'q'
head -Number sed '1,Number!d' or sed 'Numberq'
paste -s file1 file2 sed ':a;N;s/\n/\t/;ba;' file1 file2 | sed 's/\t\t/\n/'
paste -sdstr sed ':a;N;s/\n/str/;ba'
rev sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//'
tac sed -n '1! G;$p;h' or sed -n 'G;$p;h'
tail -1 sed -n '$p' or sed '$!d'
tail -Number sed ':t;$q;N;(Number+1),$D;bt'
tail -f sed -u '/./!d'
tr "\n" " " sed ':a;N;s/\n/ /;ba'
tr "A-Z" "a-z" sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'tr "a-z" "A-Z" sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'
http://hi.baidu.com/gavensun_wang/item/6c74a7138d525db1feded5c8