You are on page 1of 22

将/data/other/nginx_logs/group.abc.cn_access.

log main;替换为
/data/other/nginx_logs/${host}_${server_port}_access.log main;
grep access *|grep -v "#"|sed -e 's%\(/data/other/nginx_logs/\)\(.*\)\(_access.log main;\)%\1$
{host}_${server_port}\3%g'
意思为,将/data/other/nginx_logs/group.abc.cn_access.log 分为 3 段,一个()表示一段,
/data/other/nginx_logs/为第一段,_access.log main;为第三段,中间的为第二段,然后后面的
1 和 3 分别前面的 1 和 3 段。
sed 取 反 ( 注 释 行 的 不 替 换 , ! 放 到 后 面 , 好 奇 怪 ) sed -e '/#/!s%access_log .*;
%access_log /data/other/nginx_logs/${host}_${server_port}_access.log main%g'
/usr/local/nginx/conf/vhosts/vhost.conf

检查 nginx 配置文件有没有哪个虚拟主机没有开启日志
egrep 'server_name|access_log' test.conf|grep -v "#"|grep -v "\$server_name"|sed -n
'/server_name/{$!N;/access_log/!P;D}'
$!表示非最后一行,因为最后一行无需执行下面的命令
匹配到 server_name,然后 N;表示继续执行查找 access_log,/access_log/!P;D,表示如果没
有找到 access_log,P 表示打印出来;D 表示删除改行
sed -n '/server_name/{$!N;/access_log/!P;D}'整体意思就是,查到 server_name 并且不是最后
一行的就往下读取一行,如果不匹配 access_log 就打印出来。

调用 sed 命令有两种形式:
sed [options] 'command' file(s)
sed [options] -f scriptfile file(s)
a\
在当前行后面加入一行文本。
b lable
分支到脚本中带有标记的地方,如果分支不存在则分支到脚本的末尾。
c\
用新的文本改变本行的文本。
d
从模板块(Pattern space)位置删除行。
D
删除模板块的第一行。
i\
在当前行上面插入文本。
h
拷贝模板块的内容到内存中的缓冲区。
H
追加模板块的内容到内存中的缓冲区
g
获得内存缓冲区的内容,并替代当前模板块中的文本。
G
获得内存缓冲区的内容,并追加到当前模板块文本的后面。
l
列表不能打印字符的清单。
n
读取下一个输入行,用下一个命令处理新的行而不是用第一个命令。
N
追加下一个输入行到模板块后面并在二者间嵌入一个新行,改变当前行号码。
p
打印模板块的行。
P(大写)
打印模板块的第一行。
q
退出 Sed。
r file
从 file 中读行。
t label
if 分支,从最后一行开始,条件一旦满足或者 T,t 命令,将导致分支到带有标号的命令处,
或者到脚本的末尾。
T label
错误分支,从最后一行开始,一旦发生错误或者 T,t 命令,将导致分支到带有标号的命令
处,或者到脚本的末尾。
w file
写并追加模板块到 file 末尾。
W file
写并追加模板块的第一行到 file 末尾。
!
表示后面的命令对所有没有被选定的行发生作用。
s/re/string
用 string 替换正则表达式 re。
=
打印当前行号码。
#
把注释扩展到下一个换行符以前。
P:Print up to the first embedded newline of the current pattern space.
(就是输出模式空间开头到第一个\n 之间的内容)
D:If pattern space contains no newline, start a normal new cycle as if the d command
was issued. Otherwise, delete text in the pattern space up to the first newline, and
restart cycle with the resultant pattern space, without reading a new line of input.
(是删除模式空间开头到第一个\n(含)之间的内容,并且控制流跳到脚本的第一条语句。这里一
定要注意这句话“ and restart cycle with the resultant pattern space, without reading a
new line of input.”,即它是在不改变当前行号的情况下,从头执行的。)
这句话也充分的说明了,为什么很多人不愿意读中文翻译版书籍的原因。:-)
N : Add a newline to the pattern space, then append the next line of input to the
pattern space. If there is no more input then sed exits without processing any more
commands.
(追加下一个输入行到模板块后面并在二者间嵌入一个新行,改变当前行号码。如果没有下一个
可处理的行,则退出)
以下的是替换标记
g 表示行内全面替换。
p 表示打印行。
w 表示把行写入一个文件。
x 表示互换模板块中的文本和缓冲区中的文本。
y 表示把一个字符翻译为另外的字符(但是不用于正则表达式)

4. 选项
-e command, --command< /span>
允许多台编辑。
-h, --help
打印帮助,并显示 bug 列表的地址。
-n, --quiet, --silent
取消默认输出。
-f, --filer=script-file
引导 sed 脚本文件名。
-V, --version
打印版本和版权信息。
5. 元字符集
^
锚定行的开始 如:/^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 结尾的单词的行。
x\{m\}
重复字符 x,m 次,如:/0\{5\}/匹配包含 5 个 o 的行。
x\{m,\}
重复字符 x,至少 m 次,如:/o\{5,\}/匹配至少有 5 个 o 的行。
x\{m,n\}
重复字符 x,至少 m 次,不多于 n 次,如:/o\{5,10\}/匹配 5--10 个 o 的行。

比 如 , 要 将 目 录 /modules 下 面 所 有 文 件 中 的 zhangsan 都 修 改 成 lisi , 这 样 做 : sed -i


"s/zhangsan/lisi/g" `grep zhangsan -rl /modules`
解释一下:
-i 表示 inplace edit,就地修改文件
-r 表示搜索子目录
-l 表示输出匹配的文件名

这个命令组合很强大,要注意备份文件。

(1)sed 'y/1234567890/ABCDEFGHIJ/' test_sed


sed 'y/1234567890/ABCDEFGHIJ/' filename
ABCDEFGHIJ
BCDEFGHIJA
CDEFGHIJAB
DEFGHIJABC
注意变换关系是按两个 list 的位置对应变换
其中:test_sed 的内容是:
1234567890
2345678901
3456789012
4567890123
(2)替换每行所有匹配
sed 's/01/Ab/g' test_sed
1234567890
23456789Ab
3456789Ab2
456789Ab23
注意:第一行的 0,1 没有分别替换为 A,b

删除:d 命令
$ sed '2d' example-----删除 example 文件的第二行。
$ sed '2,$d' example-----删除 example 文件的第二行到末尾所有行。
$ sed '$d' example-----删除 example 文件的最后一行。
$ sed '/test/'d example-----删除 example 文件所有包含 test 的行。
因此我们可以这样注释配置文件中的注释行:sed '/#/'d httpd.conf >> httpd1.conf 替换:s
命令
$ sed 's/test/mytest/g' example-----在整行范围内把 test 替换为 mytest。如果没有 g 标记,则只
有每行第一个匹配的 test 被替换成 mytest。
$ sed -n 's/^test/mytest/p' example-----(-n)选项和 p 标志一起使用表示只打印那些发生替换的
行。也就是说,如果某一行开头的 test 被替换成 mytest,就打印它。
$ sed 's/^192.168.0.1/&localhost/' example-----&符号表示替换换字符串中被找到的部份。所有
以 192.168.0.1 开头的行都会被替换成它自已加 localhost,变成 192.168.0.1localhost。
$ sed -n 's/\(love\)able/\1rs/p' example-----love 被标记为 1,所有 loveable 会被替换成 lovers,
而且替换的行会被打印出来。
$ sed 's#10#100#g' example-----不论什么字符,紧跟着 s 命令的都被认为是新的分隔符,所
以,“#”在这里是分隔符,代替了默认的“/”分隔符。表示把所有 10 替换成 100。

选定行的范围:逗号
$ sed -n '/test/,/check/p' example-----所有在模板 test 和 check 所确定的范围内的行都被打印。
$ sed -n '5,/^test/p' example-----打印从第五行开始到第一个包含以 test 开始的行之间的所有行。
$ sed '/test/,/check/s/$/sed test/' example-----对于模板 test 和 west 之间的行,每行的末尾用字
符串 sed test 替换。

多点编辑:e 命令
$ sed -e '1,5d' -e 's/test/check/' example-----(-e)选项允许在同一行里执行多条命令。如例子所示,
第一条命令删除 1 至 5 行,第二条命令用 check 替换 test。命令的执 行顺序对结果有影响。如
果两个命令都是替换命令,那么第一个替换命令将影响第二个替换命令的结果。
$ sed --expression='s/test/check/' --expression='/love/d' example----- 一 个 比 -e 更 好 的 命 令 是 --
expression。它能给 sed 表达式赋值。

从文件读入:r 命令
$ sed '/test/r file' example-----file 里的内容被读进来,显示在与 test 匹配的行后面,如果匹配
多行,则 file 的内容将显示在所有匹配行的下面。

写入文件:w 命令
$ sed -n '/test/w file' example-----在 example 中所有包含 test 的行都被写入 file 里。

追加命令:a 命令
$ sed '/^test/a\\--->this is a example' example<-----'this is a example'被追加到以 test 开头的行后
面,sed 要求命令 a 后面有一个反斜杠。

插入:i 命令 $ sed '/test/i\\


new line
-------------------------' example
如果 test 被匹配,则把反斜杠后面的文本插入到匹配行的前面。
下一个:n 命令
$ sed '/test/{ n; s/aa/bb/; }' example-----如果 test 被匹配,则移动到匹配行的下一行,替换这
一行的 aa,变为 bb,并打印该行,然后继续。

变形:y 命令
$ sed '1,10y/abcde/ABCDE/' example-----把 1--10 行内所有 abcde 转变为大写,注意,正则表
达式元字符不能使用这个命令。

退出:q 命令
$ sed '10q' example-----打印完第 10 行后,退出 sed。

保持和获取:h 命令和 G 命令
$ sed -e '/test/h' -e '$G example-----在 sed 处理文件的时候,每一行都被保存在一个叫模式空
间的临时缓冲区中,除非行被删除或者输出被取消,否则所有被处理的行都将 打印在屏幕
上。接着模式空间被清空,并存入新的一行等待处理。在这个例子里,匹配 test 的行被找到
后,将存入模式空间,h 命令将其复制并存入一个称为保 持缓存区的特殊缓冲区内。第二条
语句的意思是,当到达最后一行后,G 命令取出保持缓冲区的行,然后把它放回模式空间
中,且追加到现在已经存在于模式空间中 的行的末尾。在这个例子中就是追加到最后一行。
简单来说,任何包含 test 的行都被复制并追加到该文件的末尾。

保持和互换:h 命令和 x 命令
$ sed -e '/test/h' -e '/check/x' example -----互换模式空间和保持缓冲区的内容。也就是把包含
test 与 check 的行互换。

7. 脚本

Sed 脚本是一个 sed 的命令清单,启动 Sed 时以-f 选项引导脚本文件名。Sed 对于脚本中输入


的命令非常挑剔,在命令的末尾不能有任何空白或文本,如果在一行中有多个命令,要用
分号分隔。以#开头的行为注释行,且不能跨行。

8. 小技巧
在 sed 的命令行中引用 shell 变量时要使用双引号,而不是通常所用的单引号。下面是一个
根据 name 变量的内容来删除 named.conf 文件中 zone 段的脚本:
name='zone\ "localhost"'
sed "/$name/,/};/d" named.conf

sed -i "s/oldstring/newstring/g" `grep oldstring -rl yourdir`

例如:替换/home 下所有文件中的 www.itbbs.cn 为 chinafar.com

sed -i "s/www.itbbs.cn/chinafar.com/g" `grep www.itbbs.cn -rl /home` 二、下面这条命令:


perl -pi -e 's|ABCD|Linux|g' `find ./ -type f`
将调用 perl 执行一条替换命令,把 find 命令找到的所有文件内容中的 ABCD 替换为 Linux

find ./ -type f
此命令是显示当前目录下所有的文件

上面的“s|ABCD|Linux| g”是 perl 要执行的脚本,即把所有 ABCD 替换为 Linux


如果不写最后的那个 g,“s|ABCD|Linux| ”将只替换每一行开头的 ABCD

当编辑指令(参照[section2.2])在命令列上执行时,其前必须加上选项-e。其命令格式如下:
sed-e'编辑指令 1'-e'编辑指令 2'...文件档

其中,所有编辑指令都紧接在选项-e 之後,并置於两个"'"特殊字元间。另外,命令上编辑指令的
执行是由

左而右。

一般编辑指令不多时,使用者通常直接在命令上执行它们。例如,删除 yel.dat 内 1 至 10 行资料,


并将其

馀文字中的"yellow"字串改成"black"字串。此时,可将编辑指令直接在命令上执行,其命令如
下:

sed-e'1,10d'-e's/yellow/black/g'yel.dat

在命令中,编辑指令'1,10d'(解[5])执行删除 1 至 10 行资料;编辑指令's/yellow/black/g'(解[6]),

"yellow"字串替换(substuite)成"black"字串。

2.2sed 的编辑指令

sed 编辑指令的格式如下:

[address1[,address2]]function[argument]

其中,位址参数 address1、address2 为行数或 regularexpression 字串,表示所执行编辑的资料行;


函数参

数 function[argument]为 sed 的内定函数,表示执行的编辑动作。

下面两小节,将仔细介绍位址参数的表示法与有哪些函数参数供选择。

2.2.1 位址(address)参数的表示法

实际上,位址参数表示法只是将要编辑的资料行,用它们的行数或其中的字串来代替表示它们。
下面举几个例子

说明(指令都以函数参数 d(参照[section4.2])为例):

删除档内第 10 行资料,则指令为 10d。

删除含有"man"字串的资料行时,则指令为/man/d。
删除档内第 10 行到第 200 行资料,则指令为 10,200d。

删除档内第 10 行到含"man"字串的资料行,则指令为 10,/man/d。

接下来,以位址参数的内容与其个数两点,完整说明指令中位址参数的表示法(同样也以函数
参数 d 为例)。

位址参数的内容:

位址为十进位数字:此数字表示行数。当指令执行时,将对符合此行数的资料执行函数参数指
示的编辑动作。例如,

删除资料档中的第 15 行资料,则指令为 15d(参照[section4.2])。其馀类推,如删除资料档中的


第 m 行资料,则

指令为 md。

位址为 regularexpression(参照[附录 A]):

当资料行中有符合 regularexpression 所表示的字串时,则执行函数参数指示的编辑动作。另外,


regularexpression 前後必须加上"/"。例如指令为/t.*t/d,表示删除所有含两"t"字母的资料行。其
中,"."

表示任意字元;"*"表示其前字元可重任意次,它们结合".*"表示两"t"字母间的任意字串。

位址参数的个数:在指令中,当没有位址参数时,表示全部资料行执行函数参数所指示的编辑
动作;当只有一位址

参数时,表示只有符合位址的资料行才编辑;当有两个位址参数,如 address1,address2 时,表示


对资料区执行

编辑,address1 代表起始资料行,address2 代表结束资料行。对於上述内容,以下面例子做具说


明。

例如指令为

其表示删除档内所有资料行。

例如指令为
5d

其表示删除档内第五行资料。

例如指令为

1,/apple/d

其表示删除资料区,由档内第一行至内有"apple"字串的资料行。

例如指令为

/apple/,/orange/d

其表示删除资料区,由档内含有"apple"字串至含有"orange"字串的资料行

2.2.2 有那些函数(function)参数

下页表中介绍所有 sed 的函数参数(参照[chapter4])的功能。

函数参数功能

:label 建 立 scriptfile 内 指 令 互 相 参 考 的 位 置 。 转 自 : http://blog.chinaunix.net/space.php?


uid=715007&do=blog&id=2068617
创建脚本文件 a p p e n d . s e d:
第一行是 s e d 命令解释行。脚本在这一行查找 s e d 以运行命令,这里定位在/ b i n。
第二行以/ c o m p a n y /开始,这是附加操作起始位置。a \通知 s e d 这是一个附加操
作,首先应插入一个新行。
第三行是附加操作要加入到拷贝的实际文本。
输出显示附加结果。如果要保存输出,重定向到一个文件。
[sam@chenwy sam]$ cat append.sed
#!/bin/sed -f
/company/ a\
Then suddenly it happed.
复制代码
保存它,增加可执行权限,运行
[sam@chenwy sam]chmod u+x append.sed
[sam@chenwy sam]$ ./append.sed quote.txt

复制代码
或直接用命令行:
[sam@chenwy sam]$ sed "/company/a\Then suddenly it happened."
quote.txt
[sam@chenwy sam]$ sed "/company/i\utter confusion followed." quote.txt
插入文本:
插入命令类似于附加命令,只是在指定行前面插入。和附加命令一样,它也只接受一个地
址。
如在 a t t e n d a n c e 结尾的行前插入文本 utter confusion followed。
[sam@chenwy sam]$ sed "/company/i\Utter confusion followed." quote.txt
复制代码
修改文本
修改命令将在匹配模式空间的指定行用新文本加以替代,格式如下:
将 第 一 行 The honeysuckle band played all night long for only $90 替 换 为 The
office Di b b l e band played well。首先要匹配第一行的任何部分,可使用模式‘ / H o
n e y s u c k l e /’。s e d 脚本文件为 c h a n g e . s e d。内容如下:

最后去除行尾^ M 符号,为此需做全局替换。设置替换部分为空。模式为:
‘s / ^ m / / g’,注意‘^ M’,这是一个控制字符。
在命令行里也必须用^M 控制字符耶!?
[sam@chenwy sam]$ sed 's/##/ /g;s/^0*/ /g;s/^M/ /g' dos.txt
12332 DISO 45.12
332 LPSO 23.14
1299 USPD 34.46
复制代码
或[sam@chenwy sam]$ cat dos.txt | sed 's/^0*/ /g' | sed 's/^M/ /g' | sed 's/##/ /g'
任务是在每一行末尾加一个字符串‘ p a s s e d’。
使用$命令修改各域会使工作相对容易些。首先需要匹配至少两个或更多的数字重复出现,
这样将所有的帐号加进匹配模式。

[sam@chenwy sam]$ sed 's/[0-9][0-9]*/& Passed/g' ok.txt


AC456 Passed
AC492169 Passed
AC9967 Passed
AC88345 Passed
复制代码

从 shell 向 sed 传值
要从命令行中向 s e d 传值,值得注意的是用双引号,否则功能不执行。

[sam@chenwy sam]$ NAME="It's a go situation"


[sam@chenwy sam]$ REPLACE="GO"
[sam@chenwy sam]$ echo $NAME | sed "s/go/$REPLACE/g"
It's a GO situation
复制代码

从 sed 输出中设置 shell 变量


从 s e d 输出中设置 s h e l l 变量是一个简单的替换过程。运用上面的例子,创建 s h e l l
变量 N E W- N A M E,保存上述 s e d 例子的输出结果。

[sam@chenwy sam]$ NAME="It's a go situation"


[sam@chenwy sam]$ REPLACE="GO"
[sam@chenwy sam]$ NEW_NAME=`echo $NAME | sed "s/go/$REPLACE/g"`
[sam@chenwy sam]$ echo $NEW_NAME
It's a GO situation
复制代码

这里的`是键盘左上角那个`

下面是一些一行命令集。([ ]表示空格, [ ]表示 t a b 键)


‘s / \ . $ / / g’ 删除以句点结尾行
‘-e /abcd/d’ 删除包含 a b c d 的行
‘s / [ ] [ ] [ ] * / [ ] / g’ 删除一个以上空格,用一个空格代替
‘s / ^ [ ] [ ] * / / g’ 删除行首空格,Deven:这里为什么是 2 个[ ]呢,纳闷了
‘s / \ . [ ] [ ] * / [ ] / g’ 删除句点后跟两个或更多空格,代之以一个空格
‘/ ^ $ / d’ 删除空行
‘s / ^ . / / g’ 删除第一个字符
‘s /CO L \ ( . . . \ ) / / g’ 删除紧跟 C O L 的后三个字母
‘s / ^ \ / / / g’ 从路径中删除第一个\
‘s / [ ] / [ ] / / g’ 删除所有空格并用 t a b 键替代
‘S / ^ [ ] / / g’ 删除行首所有 t a b 键
‘s / [ ] * / / g’ 删除所有 t a b 键
3. 删除首字符
s e d 删除字符串“a c c o u n t s . d o c”首字符。
echo "accounts.doc" |sed 's/^.//g'
参考:http://www.cnblogs.com/fhefh/archive/2011/11/22/2259097.html

sed 之 G、H、g、h 使用
什么是 sed?
sed 是面向流的行编辑器,所谓面向流,是指接受标准输入的输入,输出内容到标准输出上。
sed 如何处理数据?
sed 在 正 常 情 况 下 , 将 处 理 的 行 读 入 模 式 空 间 ( pattern space ) , 脚 本 中 的 “ sed-
command(sed 命令)”就一条接着一条进行处理,知道脚本执行完毕。然后该行呗输出,模
式(pattern space)被清空;接着,在重复执行刚才的动作,文件中的新的一行被读入,直
到文件处理完毕。
什么是 Pattern Space,什么是 Hold Space?
pattern space 相当于车间 sed 把流内容在这里处理。
hold space 相当于仓库,加工的半成品在这里临时储存。
PS:你可以将 pattern space 看成是一个流水线,所有的动作都是在“流水线”上执行的;而
hold space 是一个“仓库”,“流水线”上的东东都可以放到这里。
为什么要使用 sed 高级命令(G、H、g、h、n、N、x)?
由于各种各样的原因,比如用户希望在某个条件下脚本中的某个命令被执行,或者希望模
式空间得到保留以便下一次的处理,都有可能使得 sed 在处理文件的时候不按照正常的流
程来进行。这个时候,sed 设置了一些高级命令来满足用户的要求。
sed 命令:
+ g:[address[,address]]g 将 hold space 中的内容拷贝到 pattern space 中,原来 pattern space
里的内容清除
+ G:[address[,address]]G 将 hold space 中的内容 append 到 pattern space\n 后
+ h:[address[,address]]h 将 pattern space 中的内容拷贝到 hold space 中,原来的 hold space
里的内容被清除
+ H:[address[,address]]H 将 pattern space 中的内容 append 到 hold space\n 后
+ d:[address[,address]]d 删除 pattern 中的所有行,并读入下一新行到 pattern 中
+ D:[address[,address]]D 删除 multiline pattern 中的第一行,不读入下一行
PS:不论是使用 G、g 还是 H、h,它们都是将 hold space 里面的内容“copy”到 pattern space 中
或者将 pattern space 中的内容“copy”到 hold space 中。
附上英文的解释(注意其中的高亮单词):
The "h" command copies the pattern buffer into the hold buffer. The pattern buffer is unchanged.
Instead of exchanging the hold space with the pattern space, you can copy the hold space to the
pattern space with the "g" command. This deletes the pattern space. If you want to append to the
pattern space, use the "G" command. This adds a new line to the pattern space, and copies the hold
space after the new line.
示例:用 sed 模拟出 tac 的功能(倒序输出)。
文件内容
cat mm
1
2
3
解决方法:
?

sed ‘1!G;h;$!d’mm
ps:1!G 第 1 行不 执行“G”命令,从第 2 行开始执行。
$!d,最后一行不删除(保留最后 1 行)
图解分析过程,注意是每行都要执行:1!G;h;$!d
P:Pattern Space
H:Hold Space
蓝色:Hold Space 中的数据
绿色:Pattern Space 中的数据

SED 常用 command
p (sed –n) 显示行

显示行号
= =在这里是
command

g 加空行

d 删除行

/pattern/s/ 原 串 / 替 替换
换串 把 含 有
sed disable 的 行
'/disable/s/yes/no/g' 中 所 有
( g) 的 yes
s/\n// 换成 no
‘回车’换成
‘空’,删除
回车 符, 提
s/aaa/aaabbb/ 或 行,合行
s/aaa/&bbb 行 内 aaa 后
s/aaa// 插入词 bbb
行 内 删 除
词 ------ 就
是 ” 空 词 //”
替换

在 匹 配 行
zzz , 行 内
xxx 后 追 加
yyy

/zzz/a \xxx\yyy
在 匹 配 行
zzz , 另 起
/zzz/a \\
一行追加空

/zzz/a \\yyy

在 匹 配 行
zzz , 另 起
一 行 追 加
yyy

/pattern/r 22.txt' 从 文 件
111.txt 22.txt 读 出 ,
然后追加到
111.txt

Sed 最基本的 sed –n ‘p’功能=grep 的功能


sed -n grep
'/disable/p' disable
111.txt 111.txt

sed -n grep -v
'/disable/!p' disable
111.txt 111.txt
sed –n‘=’ 表示”只显示行号,但不显示行内容”
[macg@machome ~]$ sed -n '=' 111.txt
1
2
3
4

[macg@machome ~]$ sed -n '/disable/=' 111.txt


查找文件中含有 disable 的行的行号
3
9

Sed ‘=’ file 和 sed –n ‘=’ file 的区别


Sed –n ‘=’ 1.txt 只显示行号

sed = 1.txt 显示行号,同时显示每行内容(没有-n)

/pattern/s/原串 /替换串 查找并替换


# more 111.txt
this is 111file
this is 222file
disable = yes
this is file
test1 = yes
test2 = yes

[root@machome macg]# sed'/disable/s/yes/no/g' 111.txt


this is 111file
this is 222file
disable = no
this is file
test1 = yes
test2 = yes

常见的用法是把/pattern/省略,即针对所有行,直接 s 打头——s/xxx/yyy/
# sed 's/yes/no/' 111.txt
this is 111file
this is 222file
disable = no
this is file
test1 = no
test2 = no

s/xxx/yyy 缺陷:替换每行只进行一次就停止,若要全部替换,要加参数 g,s/xxx/yyy/g


标准替换 s
$ sed
只替换每一行
s/echo/test/ ttt1
中的第一个
test echo echo
“echo”字串

全 部 替 换
$ sed s/xxx/yyy/g
s/echo/test/g ttt1 将每一行中的
test test test 所 有 的 echo
都换成“test”

替换 s,别忘了尾部的/
$ sed s/echo/test ttt1
sed: -e expression_r_r #1, char 11: unterminated `s' command
$ sed s/echo/test/ ttt1

!s 不匹配的行,替换(不匹配,!加在 comand 上而不是 pattern 上)


sed '/baz/!s/foo/bar/g' !s 加/pattern/
不含有/pattern/的行替换

; 多重替换 (实际就是多语句,只不过用;加在一行里)
sed 's/scarlet/red/g;s/ruby/red/g;s/puce/red/g'
不管是“scarlet”“ruby”还是“puce”,一律换成“red”

s/\n// ‘回车’换成‘空’,删除回车符,提行,合行

/pattern/a\xxx\yyy 在匹配 pattern 的行的 xxx 后面追加 yyy


实际等于两个匹配条件:
第一个匹配条件确定行
第二个匹配条件确定行内的追加位置
sed"${LINENO}a\ FontPath \"/usr/share/fonts/ttf/zh_CN/\""

/pattern/a\\yyy 行尾追加(另起一行追加)更常用些
匹配 pattern 行,并且另起一行追加 yyy
[macg@machome
~]$ sed
'/^disable/a\\this
is a test' 111.txt
将 a\\后的内容追
加 到 disable 打
头的行后面行
(另起一行)

this is 111file
this is 222file
disable =yes
本行是空格打头,
不 是 disable 打
头 ,所以不匹配
^disable

this is 333file
this is 444file
this is file
test1 = yes
test2 = yes
disable=no
this is atest

[macg@machome
~]$ sed
'/disable/a\\this is
a test'111.txt
将 a\\后的内容追
加到含有 disable
的行后面行(另
起一行)

this is 111file
this is 222file
disable = yes
this is atest
this is 333file
this is 444file
this is file
test1 = yes
test2 = yes
disable=no
this is atest

Sed‘3a\\yyy’ 匹配行号并追加
[macg@machome
~]$ sed '3a\\ this
is a test' 111.txt
this is 111file
this is 222file
disable = yes
this is atest
this is 333file
this is 444file
this is file
test1 = yes
test2 = yes
disable=no

注意行尾追加命令 a 后面的格式,前面两个斜杠,后面无斜杠
sed '/^disable/a\\this is a test'111.txt
sed '3a\\ this is a test' 111txt
下面是错误格式:
sed '3a\this is a test\' 111.txt

前面说了行尾追加,行内追加(即行内修改)如何做?实际是采用替换 s/&
[macg@machome
~]$ sed
's/disable/& this
istest/' 111.txt
实 际 是 用 & this
istest 替 换
disable
注意 &即代表前
面的 disable
this is 111file
this is 222file
disable this is
test = yes
this is 333file
this is 444file
this is file
test1 = yes
test2 = yes
disable this is
test=no
this is 343file
this is 344file

行内追加的缺陷:如果用此法实现行尾追加,就必须把整个行不错一句的敲成 pattern
[macg@machome
~]$ sed 's/disable
= yes/& this
istest/' 111.txt
this is 111file
this is 222file
disable = yes this
istest

既然是追加到行尾,还是用 a//yyy 更合理,s/&只是在行内替换时有效

行内 aaa 后插入词 bbb----------就是替换 s/aaa/aaabbb/或 s/aaa/&bbb

行内删除词------就是”空词//”替换------s/aaa//

r ------读文件 ,然后追加
另一种追加行,从一个文件中读出的行,追加到另一个文件 pattern 后
[macg@machome
~]$ more 22.txt
222222222222file

[macg@machome
~]$ more 111.txt
this is 111file
this is 222file
disable = yes

[macg@machome
~]$ sed '/disable/r
22.txt' 111.txt
this is 111file
this is 222file
disable = yes
222222222222file

=============================sed 数字行操作=============================
======

代替/pattern/的另一种数字匹配句式-------匹配行号
数字直接表示行号
所以不需要/pattern/
sed '1,10d' 删除文件中开头的 10 行
1,10 逗号是“从…到…”
特殊符号表示行号
sed '$d' 删除文件中的最后一行
$表示最后一行

常见的两种数字标识行号用法
显示文件中的第几行
[root@machome macg]# sed -n '2p' 111.txt
this is222file
显示多行
$ sed -n '2,7p'111.txt 逗号 2,7 相当于 from … to
this is 222file
disable = yes
this is 333file
this is 444file
this is file
test1 = yes

sed '2,$d'111.txt 删除 111.txt 文件的第 2 行到末尾所有行

注意'2,7'与'2p;7p'的区别
'2,7p’表示 2 至 7 行
'2p;7p’显示 2,7 行
Command ‘=’ 显示行号
$ sed -n '/disable/=' 111.txt| sed -n '$p'
9 查找文件中含有 disable 的行的最后一行的行号

sed -n'$=' file 计算文件行数 (模拟 "wc-l")


$ -----------匹配文件最后一行
= -----------显示当前行号
说是计算行号,实际是显示最后一行的行号
# sed -n
'$=' 111.txt
5

sed 查找匹配中的最后一个并插入一行字符 2011-10-25 12:51:13


分类: LINUX
#cat httpd.conf
LoadModule access_module modules/mod_access.so
LoadModule auth_module modules/mod_auth.so
LoadModule auth_anon_module modules/mod_auth_anon.so
LoadModule auth_dbm_module modules/mod_auth_dbm.so
LoadModule auth_digest_module modules/mod_auth_digest.so
LoadModule file_cache_module modules/mod_file_cache.so
LoadModule cache_module modules/mod_cache.so
LoadModule disk_cache_module modules/mod_disk_cache.so
LoadModule mem_cache_module modules/mod_mem_cache.so
LoadModule ldap_module modules/mod_ldap.so
LoadModule auth_ldap_module modules/mod_auth_ldap.so
只输出匹配 LoadModule 的第一行:
#sed -n '/LoadModule/{p;q}' httpd.conf
LoadModule access_module modules/mod_access.so
只输出匹配 LoadModule 的最后一行:
#sed -n '/^LoadModule/h;${x;p}' httpd.conf
LoadModule auth_ldap_module modules/mod_auth_ldap.so
我想在找到最后一个匹配的字符后插入一行字符
#cat test.sh
#!/bin/bash
n=`sed -n '/^LoadModule/h;${x;p}' httpd.conf|awk '{print $2}'`
sed "/${n}/ httpd.conf This is just a test" httpd.conf
[解析]
这个要求稍微难一点,把匹配 LoadModule 的内容一直覆盖拷贝到缓冲空间中,注意是
h,H 是追加,不明白?再看看 sed 手册。这样 sed 一直读到最后一行,这时候遍历全文本只
要 是 匹 配 LoadModule 的 内 容 就 覆 盖 了 缓 冲 空 间 , 那 肯 定 缓 冲 空 间 里 是 最 后 一 个
LoadModule 行的内容,这时候 x 把模式空间和缓冲空间的内容交换,再打印输出即为最后
一样匹配的内容了。

再附上 awk 的效果:


$ awk '!a[$1]++' httpd.conf
LoadModule access_module modules/mod_access.so

$ awk '/^LoadModule/{i=$0}END{print i}' httpd.conf


LoadModule auth_ldap_module modules/mod_auth_ldap.so

You might also like