天天看点

sed基本用法

Sed是行处理命令,处理的过程是逐行将需要处理数据读入到模式空间处理,处理完成打印(默认)模式空间内容并清空模式空间,所以除非是添加特殊参数(-i),否则sed是不会修改文本内容,参数(-n)是不打印缓存空间内容,其他参数内容见下列表

常用选项

命令

功能

-n

屏蔽模式空间的自动打印,否则每行处理结束会自动打印

-i

在适当的位置修改文件(直接在文件中修改,慎用!!!)

-r

使用扩展正则表达式

-e

多项操作

-f

添加脚本文件内容到命令

定址查找

Shell> Seq 3| sed –n ‘2p’

2

##打印第2行

范围查找

Shell> seq3 | sed –n ‘1,2p’

1

## 打印第1行到第2行

多项查找-e

Shell> seq 3 | sed –n –e ‘1p’ –e ‘3p’

3

##打印第1行和第3行

 /…/查找内容,…查找值

Shell> seq 2 4 | sed –n ‘2,3p’

4

##打印第2行到第3行

Shell> seq 2 4 | sed –n ‘/2/,/3/p’

## 打印匹配2到匹配3的行之间的所有行内容

功能表

=

打印当前行号

a\

在当前模式缓存后添加一行或多行。除最后一行外,每行末尾需用“\”续行

c\

替换当前模式缓存为一行或多行文本。除最后一行外,每行末尾需用"\"续行

i\

在当前模式缓存前插入一行或多行。除最后一行外,每行末尾需用"\"续行

d

***模式空间,开始下一个操作

h

复制模式缓存到保留(暂时)缓存

H

添加模式缓存到保留(暂时)缓存

g

复制保留(暂时)缓存到模式缓存

G

添加保留(暂时)缓存到模式缓存

l

列出非打印字符

p

打印当前模式缓存

n

读入下一行到模式缓存

N

添加下一行到模式缓存

q

结束或退出sed

r

从文件中读取输入文本

!

对所选行以外的所有行应用命令

s

用一个字符串替换另一个

在行内进行全局替换

$

 末尾行

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’

2+1

2+2

## 在匹配2的行后面添加2+1,2+2

插入行i

Shell> seq 3 | sed ‘/2/i\

>3-1\

>3-2’

3-1

3-2

##在匹配2的行之前添加3-1,3-2

修改行c

Shell> seq 3 | sed ‘/2/ctwo’

two

##修改匹配2的行为two

Shell> seq 3 | sed ‘/3/c\

>three\

>four’

three

four

##修改匹配3的行位three \n four

***行d

Shell> seq 3 | sed ‘/2/d’

## ***匹配2的行

列出打印行l(通常结合-n使用)

Shell> seq 3 | sed ‘/2/l’

2$

Shell> seq 3 | sed –n ‘/2/l’

打印行p(通常结合-n使用)

Shell> seq 3 | sed ‘/2/p’

Shell> seq 3 | sed –n ‘/2/p’

结束和退出sed q(如果把sed比作一个循环,q就相当于break,-n结合d就相当于continue)

Shell> seq 3 | sed ‘/2/q’

选择取反执行命令!

Shell> seq 3 | sed ‘/2/!d’

用一个字符串替换一个字符串s

Shell> seq 3 | sed ‘s/2/two/’

全局替换g

Shell> seq 10 12 | sed ‘s/1/one/’

one0

one1

one2

Shell> seq 10 12 | sed ‘s/1/one/g’

oneone

行尾标识$

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

转换模式空间的字符为另一个字符(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’

插入一个空行

Shell> seq 3 | sed ‘/2/{x;p;x}’

## 追加空行和添加空行都是利用了模式空间和暂存空间的原理来实现

n; addr,+n; addr,~n; n~m,几个参数的应用

打印奇数行

Shell> seq 5 | sed ‘n;d’

5

Shell> seq 5 | sed ‘2~2d’

Shell> seq 5 | sed –n ‘1~1p’

模拟缓存和暂存缓存应用

模拟tac

Shell> seq 3 | sed ‘1!G;h;$!d’

模拟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

15

18

21

Shell> seq 12 3 21 | sed –n ‘/^2/p’

匹配结尾$(即行尾字符)

Shell> seq 12 3 21 | sed –n ‘/2$/p’

匹配一个字符.

Shell> seq 9 2 19

9

11

13

17

19

Shell> seq 9 2 19 | sed –n ‘/.9/p’

匹配0个或多个字符*

Shell> seq 11 13 | sed –n ‘/12*/p’

## 这个理解起来有些复杂,参考上例12*匹配的是包含1,12,122,1222…的所有字符,即匹配的是1后面跟0个或者多个2的字符窜

匹配指定字符的任意一个[]

Shell> seq 19 21 | sed –n ‘/[12][92]/p’

##上例匹配了11,19,21,29四个字符串

匹配指定字符以外的字符[^]

Shell> seq 3 | sed –n ‘/[^2]/p’

## ^是行首字符,结合[]使用就变成了取非效果,与shell正则表达相同

保存已经匹配的字符\(…\)

Shell> seq 19 21 | sed ‘s/2\(.\)/two\1/g’

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: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’

应用

替换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

## 推荐用第一种方法,虽然麻烦点,可以避免误操作

本文转自 chengchow 51CTO博客,原文链接:http://blog.51cto.com/chengchow/1423787,如需转载请自行联系原作者