Sed是行处理命令,处理的过程是逐行将需要处理数据读入到模式空间处理,处理完成打印(默认)模式空间内容并清空模式空间,所以除非是添加特殊参数(-i),否则sed是不会修改文本内容,参数(-n)是不打印缓存空间内容,其他参数内容见下列表
常用选项
命令 |
功能 |
-n |
屏蔽模式空间的自动打印,否则每行处理结束会自动打印 |
-i |
在适当的位置修改文件(直接在文件中修改,慎用!!!) |
-r |
使用扩展正则表达式 |
-e |
多项操作 |
-f |
添加脚本文件内容到命令 |
定址查找
Shell> Seq 3| sed –n ‘2p’
2
##打印第2行
范围查找
Shell> seq3 | sed –n ‘1,2p’
1
2
## 打印第1行到第2行
多项查找-e
Shell> seq 3 | sed –n –e ‘1p’ –e ‘3p’
1
3
##打印第1行和第3行
/…/查找内容,…查找值
Shell> seq 2 4 | sed –n ‘2,3p’
3
4
##打印第2行到第3行
Shell> seq 2 4 | sed –n ‘/2/,/3/p’
2
3
## 打印匹配2到匹配3的行之间的所有行内容
功能表
命令 |
功能 |
= |
打印当前行号 |
a\ |
在当前模式缓存后添加一行或多行。除最后一行外,每行末尾需用“\”续行 |
c\ |
替换当前模式缓存为一行或多行文本。除最后一行外,每行末尾需用"\"续行 |
i\ |
在当前模式缓存前插入一行或多行。除最后一行外,每行末尾需用"\"续行 |
d |
***模式空间,开始下一个操作 |
h |
复制模式缓存到保留(暂时)缓存 |
H |
添加模式缓存到保留(暂时)缓存 |
g |
复制保留(暂时)缓存到模式缓存 |
G |
添加保留(暂时)缓存到模式缓存 |
l |
列出非打印字符 |
p |
打印当前模式缓存 |
n |
读入下一行到模式缓存 |
N |
添加下一行到模式缓存 |
q |
结束或退出sed |
r |
从文件中读取输入文本 |
! |
对所选行以外的所有行应用命令 |
s |
用一个字符串替换另一个 |
g |
在行内进行全局替换 |
$ |
末尾行 |
w |
写入当前模式空间到文件 |
W |
写入当前模式空间的第一行到文件 |
x |
交换保留缓存和模式缓存的内容 |
y |
将字符替换为另一字符(不能对正则表达式使用y命令) |
Addr,+N |
处理当前行直到当前行之后N行 |
Addr,~N |
处理当前行到第N行,等同于addr,N |
n~m |
从n行开始每m行匹配一次,sed –n ‘1~2p’奇数行打印 |
常用参数举例
例:
添加行a
Shell> seq 3 | sed ‘/2/a\
>2+1\
>2+2’
1
2
2+1
2+2
3
## 在匹配2的行后面添加2+1,2+2
插入行i
Shell> seq 3 | sed ‘/2/i\
>3-1\
>3-2’
1
3-1
3-2
2
3
##在匹配2的行之前添加3-1,3-2
修改行c
Shell> seq 3 | sed ‘/2/ctwo’
1
two
3
##修改匹配2的行为two
Shell> seq 3 | sed ‘/3/c\
>three\
>four’
1
2
three
four
##修改匹配3的行位three \n four
***行d
Shell> seq 3 | sed ‘/2/d’
1
3
## ***匹配2的行
列出打印行l(通常结合-n使用)
Shell> seq 3 | sed ‘/2/l’
2
2$
2
3
Shell> seq 3 | sed –n ‘/2/l’
2$
打印行p(通常结合-n使用)
Shell> seq 3 | sed ‘/2/p’
1
2
2
3
Shell> seq 3 | sed –n ‘/2/p’
2
结束和退出sed q(如果把sed比作一个循环,q就相当于break,-n结合d就相当于continue)
Shell> seq 3 | sed ‘/2/q’
1
2
选择取反执行命令!
Shell> seq 3 | sed ‘/2/d’
1
3
Shell> seq 3 | sed ‘/2/!d’
2
用一个字符串替换一个字符串s
Shell> seq 3 | sed ‘s/2/two/’
1
two
3
全局替换g
Shell> seq 10 12 | sed ‘s/1/one/’
one0
one1
one2
Shell> seq 10 12 | sed ‘s/1/one/g’
one0
oneone
one2
行尾标识$
Shell> seq 10 12 | sed ‘s/1$/one/g’
10
1one
12
行首标识^
Shell> seq 10 12 | sed ‘s/^1/one/g’
One0
One1
One2
写入当前模式空间内容到文件
Shell> seq 3 | sed –n ‘2wpp’
Shell> cat pp
2
转换模式空间的字符为另一个字符(y/source/dest/)
Shell> seq 212 214 | sed ‘y/1/a/’
2a2
2a3
2a4
对多个字符同时转换(不能转换字符串)
Shell> seq 212 214 | sed ‘y/12/IR/’
RIR
RI3
RI4
追加一个空行
Shell> seq 3 | sed ‘/2/G’
1
2
3
插入一个空行
Shell> seq 3 | sed ‘/2/{x;p;x}’
1
2
3
## 追加空行和添加空行都是利用了模式空间和暂存空间的原理来实现
n; addr,+n; addr,~n; n~m,几个参数的应用
打印奇数行
Shell> seq 5 | sed ‘n;d’
1
3
5
Shell> seq 5 | sed ‘2~2d’
1
3
5
Shell> seq 5 | sed –n ‘1~1p’
1
3
5
模拟缓存和暂存缓存应用
模拟tac
Shell> seq 3 | sed ‘1!G;h;$!d’
3
2
1
模拟rev
Shell> echo `seq 3` | sed ‘/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//’
3 2 1
元字符
元字符 |
功能 |
示例 |
^ |
行首定位符 |
/^my/ 匹配所有以my开头的行 |
$ |
行尾定位符 |
/my$/ 匹配所有以my结尾的行 |
. |
匹配除换行符以外的单个字符 |
/m..y/ 匹配包含字母m,后跟两个任意字符,再跟字母y的行 |
* |
匹配零个或多个前导字符 |
/my*/ 匹配包含字母m,后跟零个或多个y字母的行 |
[] |
匹配指定字符组内的任一字符 |
/[Mm]y/ 匹配包含My或my的行 |
[^] |
匹配不在指定字符组内的任一字符 |
/[^Mm]y/ 匹配包含y,但y之前的那个字符不是M或m的行 |
\(..\) |
保存已匹配的字符 |
1,20s/\(you\)self/\1r/ 标记元字符之间的模式,并将其保存为标签1,之后可以使用\1来引用它。最多可以定义9个标签,从左边开始编号,最左边的是第一个。此例中,对第1到第20行进行处理,you被保存为标签1,如果发现youself,则替换为your。 |
& |
保存查找串以便在替换串中引用 |
s/my/**&**/ 符号&代表查找串。my将被替换为**my** |
\< |
词首定位符 |
/\<my/ 匹配包含以my开头的单词的行 |
\> |
词尾定位符 |
/my\>/ 匹配包含以my结尾的单词的行 |
x\{m\} |
连续m个x |
/9\{5\}/ 匹配包含连续5个9的行 |
x\{m,\} |
至少m个x |
/9\{5,\}/ 匹配包含至少连续5个9的行 |
x\{m,n\} |
至少m个,但不超过n个x |
/9\{5,7\}/ 匹配包含连续5到7个9的行 |
例:
匹配开头^(既即行首字符)
Shell> swq 12 3 21
12
15
18
21
Shell> seq 12 3 21 | sed –n ‘/^2/p’
21
匹配结尾$(即行尾字符)
Shell> seq 12 3 21 | sed –n ‘/2$/p’
12
匹配一个字符.
Shell> seq 9 2 19
9
11
13
15
17
19
Shell> seq 9 2 19 | sed –n ‘/.9/p’
19
匹配0个或多个字符*
Shell> seq 11 13 | sed –n ‘/12*/p’
11
12
13
## 这个理解起来有些复杂,参考上例12*匹配的是包含1,12,122,1222…的所有字符,即匹配的是1后面跟0个或者多个2的字符窜
匹配指定字符的任意一个[]
Shell> seq 19 21 | sed –n ‘/[12][92]/p’
19
21
##上例匹配了11,19,21,29四个字符串
匹配指定字符以外的字符[^]
Shell> seq 3 | sed –n ‘/[^2]/p’
1
3
## ^是行首字符,结合[]使用就变成了取非效果,与shell正则表达相同
保存已经匹配的字符\(…\)
Shell> seq 19 21 | sed ‘s/2\(.\)/two\1/g’
19
two0
two1
## 替换2后面任意字符为two后面任意字符
匹配查找的字符串&
Shell> seq 100 102 | sed ‘s/10[0-9]/&a/g’
100a
101a
102a
## 这里&=10[0-9]
匹配单词开头\<
Shell> echo “109 901 910 102” | sed ‘’s/1/one/g
One09 90one 9one0 one02
Shell> echo “109 901 910 102” | sed ‘s/^1/one/g’
One09 901 910 102
Shell> echo “109 901 910 102” | sed ‘s/\<1/one/g’
One09 901 910 one02
## \<和^都是匹配开头,不同的是\<分隔符是空格,TAB和换行,^分隔符是换行
匹配单词结尾\>
Shell> echo “109 901 910 102” | sed ‘s/1\>/one/g’
109 90one 910 102
## 同上解
匹配M个相同字符a{m}
Shell> ifconfig | sed –n ‘/[0-9]\{3\}\.[0-9]\{3\}\.[0-9]\{3\}\.[0-9]\{3\}/p’
Inet addr: 192.168.254.123 Bcast:192.168.254.255 Mask:255.255.255.0
##只有所有位都是3的地址是被匹配的
匹配M-N个相同字符a{n,m}
Shell> ifconfig |sed –n “/[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/p”
Inet addr: 192.168.254.123 Bcast:192.168.254.255 Mask:255.255.255.0
Inet addr:127.0.0.1Mask:255.0.0.0
## 所有地址都被匹配
匹配大于等于N个相同字符a{n,}
Shell> ifconfig | sed –n ‘/[0-9]\{1,\}\. [0-9]\{1,\}\. [0-9]\{1,\}\. [0-9]\{1,\}/p’
Inet addr: 192.168.254.123 Bcast:192.168.254.255 Mask:255.255.255.0
Inet addr:127.0.0.1Mask:255.0.0.0
## 所有地址都被匹配
应用
替换my.cnf所有IP地址为本地IP地址
Shell> mv /etc/mysql/my.cnf /etc/mysql/my.cnf.old;\
IP=`ifconfig | awk ‘{FS=”[ |:]+”} NR==2 {print $4}’`;\
sed “/bind-address/c\
bind-address\t\t\t\t= $IP” /etc/mysql/my.cnf.old> /etc/mysl/my.cnf
||
shell> IP=`ifconfig | awk ‘{FS=”[ |:]+” NR==2 {print $4}}’`;\
sed -i “/bind-address/c\
bind-address\t\t\t\t= $IP” my.cnf
## 推荐用第一种方法,虽然麻烦点,可以避免误操作