码迷,mamicode.com
首页 > 其他好文 > 详细

SED总结

时间:2015-07-27 07:01:07      阅读:388      评论:0      收藏:0      [点我收藏+]

标签:

一、Sed简介

Sed:Stream Editor  流式编辑器 又称行编辑器,每次只编辑一行。Sed工作是在“模式空间”中进行的,并不操作源文件。对源文件无危害。

 

二、Sed使用格式

    Sed命令的常用格式如下:

(1)Sed [options] ‘script’ input_file…

(2)Sed [options] –f script_file input_file…

(3)Sed [options] ‘ADDR1,ADDR2command’ input_file…

例如:#sed ’1,2d’ fstab 就可以将fstab的前两行删除并显示出来,但是它不会改变源文件。

#Sed ‘1,2!d’ fstab 表示删除除第一行和第二行之外的所有行。

(4)Sed [options] ‘/PATTERN/command’ input_file……

&:s/l..e/&er/:表示引用前面匹配到的所有字符。

例如:sed ‘/[[:upper:]]/d’ binary.sh 表示删除所有的大写字母的行。

(5)Sed ‘/PATTERN1/,/PATTERN2/command’ input_file……

说明:这表示从第一次被PATTERN1匹配到的行到第一次被PATTERN2匹配到的中间的所有行执行command命令。

 

三、Sed的常用选项:

    -n:只显示sed匹配到的行。其余行不显示。下文有范例。

-i :可以直接操作原文件。默认情况下sed不会改变原文件,但是-i选项可以修改原文件,此选项应慎用。

-r:可以使用标准正则表达式。默认情况下sed只支持基本正则表达式,但是加上-r选项后则支持扩展正则表达式

-e:多脚本共用。可以同时执行多个命令。例如:

 [root@localhost ~]# sed -e ‘s@\@H\1@g‘ -e ‘s@\(l..e\)\.@\1r.@g‘ test

He love His lover.

She like Her liker.

Dove love Her liker.

也可以这样用,中间用分号隔开:

[root@localhost ~]# sed ‘s@\@H\1@g;s@\(l..e\)\.@\1r.@g‘ test

 

四、Sed的常用命令

(1)P:模式空间中的文本在处理之前,每一次都会先显示一下;用p命令后再显示一下,即:匹配到的文本显示两次:例如:

 [root@localhost ~]# sed ‘1,2p‘ fstab

/dev/vol0/root          /                       ext3    defaults                   1 1

/dev/vol0/root          /                       ext3    defaults                   1 1

/dev/vol0/home        /home               ext3    defaults                   1 2

/dev/vol0/home        /home               ext3    defaults                   1 2

LABEL=/boot         /boot                ext3    defaults                   1 2

tmpfs                      /dev/shm           tmpfs   defaults                   0 0

devpts                    /dev/pts             devpts  gid=5,mode=620   0 0

sysfs                      /sys                      sysfs    defaults                 0 0

proc                     /proc                   proc    defaults                   0 0

LABEL=SWAP-sda3       swap       swap    defaults                 0 0

我们可以看到第1,2行显示了两次。如果你只想显示用sed处理的行,则可在其前加-n选项。例如:sed  -n ‘1,2p’ fstab 其显示结果如下:

root@localhost ~]# sed -n ‘1,2p‘ fstab

/dev/vol0/root             /                        ext3    defaults        1 1

/dev/vol0/home          /home                 ext3    defaults        1 2

(2)a  \:表示在模式匹配到的行后面添加新内容;

i  \:表示在模式匹配到的行前面添加新内容;

           /n:实现添加多行。如下例所示:

 [root@localhost ~]# sed ‘/#/a \ This is a comment line.\nIt can be ignore.‘ test.sh

#!/bin/bash

 This is a comment line.

It can be ignore.

#

 This is a comment line.

It can be ignore.

JUSER() {

    if id -u root &> /dev/null;then

       echo "Exists"

    else

       echo "No this user."

    fi

}

JUSER &> /dev/null

echo $?

这表示在#行的后面加上两行文字,如果将a换成i则表示在#行的前面添加文字。

注意:sed ‘/#/!i \ This is a comment line.\nIt can be ignore.‘ test.sh,如果在i前面加!表示对除了匹配到的行的其他行的前面添加以上两行。这样大家基本明白了a,i命令的使用方法了吧。

 (3)r FILE:表示读取某一个文件。例如:

root@localhost ~]# sed ‘2r c.txt‘ c.sh  #表示在c.sh的第二行添加c.txt的内容。

#!/bin/bash

#

This is my first lesson.

Think you!

line 1

line 2

line 3

 [root@localhost ~]# sed ‘/^#/r c.txt‘ c.sh  #表示在c.sh的#开头的行后面添加c.txt的内容。

#!/bin/bash

This is my first lesson.

Think you!

#

This is my first lesson.

Think you!

line 1

line 2

line 3

 

(4)w FILE: 可以将模式匹配到的行保存下来。例如:

root@localhost ~]# cat c.sh     #显示c.sh中的内容

#!/bin/bash

#

line 1

line 2

line 3

[root@localhost ~]# sed -n ‘/^#/w cc.sh‘ c.sh  #将c.sh文件中以#开头的行保存在cc.sh中

[root@localhost ~]# cat cc.sh                         #cc.sh的内容

#!/bin/bash

#

(5)s:s/PATTERN/string/[g|i]   表示搜索符号PATTERN的内容,将其替换为string。

       g:表示将搜索到的内容全部替换。

       i:表示将搜索到的内容忽略大小写。

       如果PATTERN中含有与分隔符相同的字符时,可以将分隔符替换为其他符号。例如:s@PATTERN@string@[g|i]

范例如下:

[root@localhost ~]# cat test        #显示test的内容

He love his love.

She like her like.

Dove love her like.

[root@localhost ~]# sed ‘s@\(l..e\)\.@\1r.@‘ test  #在最后一个单词后面加r,注意第.

He love his lover.                                                #前面要加转义字符\

She like her liker.

Dove love her liker.

[root@localhost ~]# sed ‘s@\@H\1@g‘ test  #将以h开头的单词替换

He love His love.                                       #为以H开头

She like Her like.

Dove love Her like.

 

(6)n:以覆盖的方式读去下一行。

         N:以追加的方式读取下一行。例如:

[root@localhost ~]# cat test          #test中的内容

He love his love.

She like her like.

Dove love her like.

four line

[root@localhost ~]# sed -n ‘n;p‘ test   #使用n时的效果

She like her like.

four line

[root@localhost ~]# sed ‘n;d‘ test     #只显示偶数行。

He love his love.

Dove love her like.

[root@localhost ~]# sed -n ‘N;p‘ test   #使用N时的效果

He love his love.

She like her like.

Dove love her like.

four line

[root@localhost ~]# sed ‘N;N;s@\n@ @g‘ test  #表示将前三行合并为一行

He love his love. She like her like. Dove love her like.

four line

[root@localhost ~]# sed ‘/\.$/!N;s@\n@ @g;s/bad animal/BAD ANIMAL/g‘ test 

He love his love.

She like her like.

Dove love her like.

four line Wendy is BAD ANIMAL.

Blair is a BAD ANIMAL.

这题目较复杂:(1)/\.s/!N:表示先搜索不已点号结尾的行,(2)s@\n@ @g:将搜索到的行去掉换行符 (3)将小写的bad animal 替换为BAD ANIMAL. 

(7) h:将模式空间中的内容以覆盖的方式复制到保留空间。

           H:将模式空间中的内容以追加的方式复制到保留空间。

  g:将保留空间的内容以覆盖的方式复制到模式空间。

  G:将保留空间的内容以追加的方式复制到模式空间。例如:

[root@localhost ~]# cat newfile             #显示文件中的内容

line 1

line 2

line 3

[root@localhost ~]# sed -n ‘h;n;G;h;n;G;p‘ newfile  #将文件中的行倒序排列

line 3

line 2

line 1

 

(8)b:跳转,掠过符合条件的行。例如:

[root@localhost ~]# sed ‘1b;y/123/456/‘ newfile

line 1

line 5

line 6

此例表示:跳过第一行,将其他各行的123替换为456;其中y表示替换的意思。

b lable:表示跳转到某个位置。例如

[root@localhost ~]# cat newfile

line 1

line

line 3

line

[root@localhost ~]# sed ‘/.*[[:digit:]].*/b para;s/.*/% &/;:para;s/.*[0-9].*/# &/g‘ newfile

# line 1

% line

# line 3

% line

此例表示,将带数字的行前添加#,不带数字前添加%;定义para为跳转符。这个参数可以随意指定。

 

本文只是对sed的一些常用命令和选项做介绍,其余命令可查看帮助手册。谢谢!

 

 

 最近在处理一个文本,打算用sed命令来处理,但是由于经常情况下都是做简单的替换,所以对sed不是很熟悉,最近两天由于项目工作量比较小,所以就今天抽空整体学习下了sed。

先说下自己遇到处理的一个问题:

 

例子:

 

文件内容:testfile

 

abc

 

     aaaaaaaaaa

 

     bbbbbbbbbb

 

 

 

dfg

 

     jjjjjjjjj

 

hjk

 

处理结果:获取abc到dfg之间的内容,不包括abc和dfg这两行,想要sed直接一句话处理一直有问题,所以等整体学习下sed,我们再来提出一个解决问题的方法吧。

 

 

 

1、sed 的工作原理

 

sed把当前正在处理的行保存在一个临时缓冲区中,这个缓冲区称为临时空间或者模式空间,sed处理完模式空间中的行后,就把该行发送到屏幕上,并将该行从模式空间中删除

 

 

 

2、把正则表达式分隔符换成另外一个字符,比如h,只要在这个字符的前面加一个反斜杠,在正则表达式后面也更上这个字符就可以了,例子:

 

[root@xm_41 tmp]# sed -n ‘/abc/p‘ testfile
abc

 

[root@xm_41 tmp]# sed -n ‘\habchp‘ testfile
abc

 

注:如果斜杠本身是正则表达式的一部分,必须在它们面前加上反斜杠,以免和分隔符混淆,此时就可以采用上面的这种方法。

 

 

 

3、sed返回码

 

如果在指定的文件中找到指定的模式,grep将返回码退出状态0,如果没有找到则为1,sed不一样,不管是否找到指定的模式,只要语法不出错都是返回0。

 

[root@xm_41 tmp]# grep ‘beauty‘ testfile 
[root@xm_41 tmp]# echo $?
1
[root@xm_41 tmp]# sed -n ‘/beauty/p‘ testfile 
[root@xm_41 tmp]# echo $?
0

 

 

 

4、定址

 

决定对那些进行编辑,地址可以是数字、正则表达式以及两者的结合

 

[root@xm_41 tmp]# sed ‘1,2d‘ testfile 
     bbbbbbbbbb

dfg
     jjjjjjjjj
hjk
[root@xm_41 tmp]# sed -n ‘/[ab]/p‘ testfile 
abc
     aaaaaaaaaa
     bbbbbbbbbb

 

 

 

5、命令和选项

 

 命令  功能 
a\  在当前行后添加一行或多行。多行时除最后一行外,每行末尾需用“\”续行
c\  用此符号后的新文本替换当前行中的文本。多行时除最后一行外,每行末尾需用"\"续行 
i\  在当前行之前插入文本。多行时除最后一行外,每行末尾需用"\"续行 
d  删除行 
h  把模式空间里的内容复制到暂存缓冲区 
H  把模式空间里的内容追加到暂存缓冲区 
g  把暂存缓冲区里的内容复制到模式空间,覆盖原有的内容 
G  把暂存缓冲区的内容追加到模式空间里,追加在原有内容的后面 
l  列出非打印字符 
n  读入下一输入行,并从下一条命令而不是第一条命令开始对其的处理 
q  结束或退出sed 
r  从文件中读取输入行 
!  对所选行以外的所有行应用命令 
s  用一个字符串替换另一个 

 


g  在行内进行全局替换 
p  打印行
w  将所选的行写入文件 
x  交换暂存缓冲区与模式空间的内容 
y  将字符替换为另一字符(不能对正则表达式使用y命令)

 

 

 

6、元字符

 

 元字符  功能  示例 
^  行首定位符  /^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结尾的单词的行 
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的行 

 

 

 

7、sed选项

 

-e 允许多项编辑

 

-f 指定sed脚本文件名

 

-n 取消默认的输出

 

 

 

8、sed范例

 

(1)、d用于删除输入的行,$代表文件的最后一行

 

[root@xm_41 tmp]# sed ‘2,$d‘ testfile 
abc

 

(2)、对于s替换命名,紧跟s后面的字符就是查找和替换的分隔符

 

[root@xm_41 tmp]# sed -n ‘s/abc/china/p‘  testfile 
china

 

[root@xm_41 tmp]# sed -n ‘s=abc=china=p‘ testfile 
china

 

上面用符号‘=‘作为分隔符

 

(3)、r命令是读命令,读取文件内容追加到另外一个文件

 

[root@xm_41 tmp]# cat data
china china
[root@xm_41 tmp]# sed ‘/abc/r data‘ testfile 
abc
china china
     aaaaaaaaaa
     bbbbbbbbbb

dfg
     jjjjjjjjj
hjk

 

读取data中的内容追加到testfile中

 

(4)、w是写的内容

 

[root@xm_41 tmp]# sed ‘/abc/w newdata‘ testfile 
abc
     aaaaaaaaaa
     bbbbbbbbbb

dfg
     jjjjjjjjj
hjk
[root@xm_41 tmp]# cat newdata 
abc

 

(5)、a命令

 

[root@xm_41 tmp]# sed ‘/abc/a\china‘ testfile 
abc
china
     aaaaaaaaaa
     bbbbbbbbbb

dfg
     jjjjjjjjj
hjk

 

(6)、i命令

 

[root@xm_41 tmp]# sed ‘/abc/i\china‘ testfile 
china
abc
     aaaaaaaaaa
     bbbbbbbbbb

dfg
     jjjjjjjjj
hjk

 

(7)、c命令

 

[root@xm_41 tmp]# sed ‘/abc/c\china\‘ testfile 
china
     aaaaaaaaaa
     bbbbbbbbbb

dfg
     jjjjjjjjj
hjk

 

注意:a和i的区别就是一个插入在后面一个是插入在前面,而c直接是替换掉整行,和s差别是s是替换匹配的

 

(8)、获取下一行:n的命令和N命令

 

两者命令的区别是n是读取下一行到模式空间,会替换掉原的行,而N是读取下一行追加到模式缓冲区,相当于此时模式空间中会有两行

 

[root@xm_41 tmp]# sed ‘/abc/{n;s/a/q/g}‘ testfile 
abc
     qqqqqqqqqq
     bbbbbbbbbb

dfg
     jjjjjjjjj
hjk
[root@xm_41 tmp]# sed ‘/abc/{N;s/a/q/g}‘ testfile 
qbc
     qqqqqqqqqq
     bbbbbbbbbb

dfg
     jjjjjjjjj
hjk

 

对于n命令来说只有第二行的a被替换成了q,而对于N命令来说一二两行的a都替换成了q

 

(9)、y命令

 

[root@xm_41 tmp]# sed ‘1,2y/a/A/‘ testfile 
Abc
     AAAAAAAAAA
     bbbbbbbbbb

dfg
     jjjjjjjjj
hjk

 

有点和tr命令类似

 

引申:学习下tr命令

 

a、替换

 

[root@xm_41 tmp]# tr "a" "A" < testfile 
Abc
     AAAAAAAAAA
     bbbbbbbbbb

dfg
     jjjjjjjjj
hjk

 

b、去除重复的字符

 

[root@xm_41 tmp]# tr -s "a" < testfile 
abc
     a
     bbbbbbbbbb

dfg
     jjjjjjjjj
hjk

 

 

 

注意:tr -s "\n" < testfile 可以去除空行

 

c、删除指定的字符

 

[root@xm_41 tmp]# tr -d "a" < testfile 

bc
     
     bbbbbbbbbb

dfg
     jjjjjjjjj
hjk

d、c命令,去反义

 

[root@xm_41 tmp]# tr -cd "a\n" < testfile 
a
aaaaaaaaaa

 

(9)、q命令直接退出不在往下执行

 

(10)、h和H命令:把模式空间的数据放到缓冲区中去

 

[root@xm_41 tmp]# sed ‘/abc/h;/dfg/h;g‘ testfile 
abc
abc
abc
abc
dfg
dfg
dfg
[root@xm_41 tmp]# sed ‘/abc/h;/dfg/H;g‘ testfile 
abc
abc
abc
abc
abc
dfg
abc
dfg
abc
dfg

 

 

 

注意:h和H的区别,一个是替换缓冲区的内容,一个是把内容追加到缓冲区

 

(11)、g命令和G命令:从缓冲区中取出展示到模式空间

 

[root@xm_41 tmp]# sed ‘/abc/h;g‘ testfile 
abc
abc
abc
abc
abc
abc
abc

 

 

 

[root@xm_41 tmp]# sed ‘/abc/h;G‘ testfile 
abc
abc
     aaaaaaaaaa
abc
     bbbbbbbbbb
abc

abc
dfg
abc
     jjjjjjjjj
abc
hjk
abc

 

注意:g和G区别一个是替换一个是追加

 

(12)、x命令:缓冲区和模式空间的数据替换

 

[root@xm_41 tmp]# sed ‘/abc/h;/dfg/x‘ testfile 
abc
     aaaaaaaaaa
     bbbbbbbbbb

abc
     jjjjjjjjj
hjk

 


(13)、显示行号

 

[root@xm_41 tmp]# sed = < testfile | sed ‘N;s/\n/:/‘ 
1:abc
2:     aaaaaaaaaa
3:     bbbbbbbbbb
4:
5:dfg
6:     jjjjjjjjj
7:hjk
 
(14)、P命令:只输出模式空间中的第一行
[root@xm_41 tmp]# sed ‘N;P‘ testfile 
abc
abc
     aaaaaaaaaa
     bbbbbbbbbb
     bbbbbbbbbb

dfg
dfg
     jjjjjjjjj
hjk
详解:所先sed读取第一行,然后N命令在读取一行变成abc\naaaaaaa\n,然后P打印出abc这行,当前行处理输出abc\naaaaa\n;接下去N命令在读取bbbbbbb;循环下去
[root@xm_41 tmp]# sed ‘N;p‘ testfile 
abc
     aaaaaaaaaa
abc
     aaaaaaaaaa
     bbbbbbbbbb

     bbbbbbbbbb

dfg
     jjjjjjjjj
dfg
     jjjjjjjjj
hjk
P和p的差别,P是指打印模式空间中的第一块,而p是打印所有的
 
(15)、D命令:只删除模式空间中的第一行
理由同14一样

 

 

 

 

sed是简单小巧但功能非常强大的工具。在上一篇博客中自己注解了sed的info文档中那些比较复杂的脚本示例,最近工作中使用到sed,复习了一下,再做一篇总结放在这里:

 

  • sed有两块缓冲区:pattern space和hold space。pattern space中存放待处理的目标文本,hold space供程序员自己使用。
  • sed处理流程:
    1. 清空pattern space。(如果这是对该输入流的第一次读取,则也将hold space初始化为空)
    2. 从输入流中读取一行,去除末尾的换行符,将其放入pattern space。
    3. 执 行sed脚本。sed脚本由一系列命令组成。因为sed是按行处理,所以sed命令的含义主要是“对于什么样的行,则进行什么样的处理”。例如,“把第3 行删除”,或者“如果这一行包含this,则把其中的this替换成that”。其中“包含什么样的行”由address指定,“执行什么样的处理”由 sed命令序列表达。
    4. 脚本执行完毕,如果输入流中还有内容,转至1,开始下一轮处理。
  • 所以,学习sed,就是学习如何“指定需要处理的行”(address),以及学习我们能使用sed“进行什么样的操作”(command)。
  • 注 意的是,sed都是按行处理,即使指定的是一个address range,比如sed -e ‘3,7s/this/that/g‘,s命令会被执行5次(从第3行到第7行每行执行一次)而不是只执行一次就将第3到第7行的所有this换成 that。可以使用sed的N命令或者其他命令读入多行文本到pattern space。
  • sed使用/M或者/m来切换 到"multiple line mode"(即多行处理模式)。所谓“多行处理模式”,是指在这种模式下,元字符^不再表示字符串起始位置,而是表示换行符后面的空字符串,元字符$也不 再表示字符串末尾位置,而是表示换行符前面的空字符串。自我感觉这种模式没有任何作用,只会把问题弄得混乱,因为完全可以使用\n来匹配换行符,将其作为 普通字符用在正则表达式中。
  • sed中的调试非常简便,可以使用上一篇博客中的那个python脚本来调试sed,也可以使用sed中的l命令或者p命令来输出pattern space中的内容进行调试。在以下的“去除多余空行“的方法二中使用l命令进行调试。

 

练习几个例子,以便将来温习:准备以下文件:

 

  1. hbwang@jcwkyl:/home/hbwang$cat test  
  2. abc  
  3. de f  
  4. 1     2 345  
  5. en d  
  6.   
  7.   
  8.   
  9.   
  10. int main () {  
  11.     printf("hello\n");  
  12.     return 0;  
  13. }  
  14.   
  15.   
  16. last empty  

 

    1. 去掉所有换行符:
      • 方法一:vim打开文件,执行:1,$s/\n//即可。这里使用sed的方法:读入一行,删除换行符,再读入下一行,直到整个文件处理结束。实现如下:
        1. hbwang@jcwkyl:/home/hbwang$sed -e :a -e "N;s/\n//;ba" test  
        2. abcde f1     2 345en dint main () {    printf("hello\n");    return 0;}last empty  
        命令解释:-e参数用来添加执行命令。":a"用来设置一个名字为a的label以供后来的goto使用(sed中有两个跳转命令:b和t。b为无条件跳转,t为当上一个s命令替换成功时跳转)。"N;s/\n//;ba"用分号隔开了三条命令。在执行这些命令之前,pattern space中存放着一个输入行(其末尾的换行符已经去掉),N命令在pattern space后面追加一个换行符并从输入流中读入下一行。此时pattern space中的内容就是输入流中的连续两行文本的拷贝,用s命令去掉换行符,然后再用b命令无条件跳转到label ":a"上继续处理后面的文本。执行结果如上所示,成功达到了目标。
        这里有个细节。如果复习一下开头所说的sed的处理流程(execution cycle),会发现每一轮开始sed都会自己删除pattern space的内容并从输入流中读取下一行。照刚才这种方法,pattern space中两行之间的换行符去掉了,但第二行末尾的换行符似乎没有机会被删除。然而实验结果证明这种方法是对的。不妨再验证一下,在每次替换后用l命令查看一下pattern space中的内容(l命令会以raw format来输出pattern space中的内容,其中特殊字符都会以其转义形式输出,例如换行符会被输出成为\n,字符串末尾会输出一个$来标记):
        1. hbwang@jcwkyl:/home/hbwang$sed -e :a -e "N;s/\n//;l;ba" test  
        2. abcde f$  
        3. abcde f1     2 345$  
        4. abcde f1     2 345en d$  
        5. abcde f1     2 345en d$  
        6. abcde f1     2 345en d$  
        7. abcde f1     2 345en d$  
        8. abcde f1     2 345en d$  
        9. abcde f1     2 345en dint main () {$  
        10. abcde f1     2 345en dint main () {    printf("hello\\n");$  
        11. abcde f1     2 345en dint main () {    printf("hello\\n");    return \  
        12. 0;$  
        13. abcde f1     2 345en dint main () {    printf("hello\\n");    return \  
        14. 0;}$  
        15. abcde f1     2 345en dint main () {    printf("hello\\n");    return \  
        16. 0;}$  
        17. abcde f1     2 345en dint main () {    printf("hello\\n");    return \  
        18. 0;}$  
        19. abcde f1     2 345en dint main () {    printf("hello\\n");    return \  
        20. 0;}last empty$  
        21. abcde f1     2 345en dint main () {    printf("hello\n");    return 0;}last empty  
        可以看到,pattern space中的内容一直没有被清除:删除第一、二行之间的换行符后,又读入第三行,删除第二、三行之间的换行符,直到整个文件处理完毕。
        那如果要实现刚才设想的情况,只删除第奇数个换行符而保留第偶数个换行符,只需要让sed去除一个换行符后直接开始下一轮执行即可,用d命令可以做到:
        1. hbwang@jcwkyl:/home/hbwang$sed -e :a -e "N;s/\n//;p;d" test  
        2. abcde f  
        3. 1     2 345en d  
        4.   
        5.   
        6. int main () {    printf("hello\n");  
        7.     return 0;}  
        8.   
        9. last empty  
        d命令会删除pattern space中的内容,所以在删除前先用p命令把pattern space中的内容输出出来。
      • 方法二:读入整个文件,用一条命令删除所有换行符。
        因为sed在每个cycle开始都会清空pattern space,所以要使用sed读入整个文件,要么在一个cycle中用一个循环把所有行都读入到pattern space,要么利用hold space不会被清空的特性,每读一行就把它添加到hold space中,整个文件读完,hold space中也就保存了整个文件的内容。sed中只支持两种跳转方式,即:
        • if(是目标行) { /* handle */ } else { /*非目标行 */}
        • if(替换成功) { goto label; } else { /* 继续执行 */}
        用第一种跳转方式读取整个文件容易些,实现如下:
        1. hbwang@jcwkyl:/home/hbwang$sed -e ‘$!{H;d}‘ -e ‘${H;x;s/\n//g;}‘ test  
        2. abcde f1     2 345en dint main () {    printf("hello\n");    return 0;}last empty  
        3.   
        4. 或者:  
        5.   
        6. hbwang@jcwkyl:/home/hbwang$sed -n -e ‘$!H‘ -e ‘${H;x;s/\n//gp}‘ test  
        7. abcde f1     2 345en dint main () {    printf("hello\n");    return 0;}last empty  
        8.   
        9. 或者:  
        10.   
        11. hbwang@jcwkyl:/home/hbwang$sed -n -e ‘$!H‘ -e ‘${H;g;s/\n//gp}‘ test  
        12. abcde f1     2 345en dint main () {    printf("hello\n");    return 0;}last empty  

        其中,"$"是最后一行地址,"$!"表示“不是最后一行”。实现1,‘$!{H,d}‘,表示如果不是最后一行,用H命令在hold space上添加一个换行符并把pattern space中的内容append到hold space,然后删除pattern space(如果不删除,因为我们没有指定-n选项,所以pattern space的内容会在进入下一轮cycle前输出出来),‘${H;x;s\n//g;}‘表示如果是最后一行,用H命令把最后一行添加到hold space,用x命令交换pattern space和hold space(其目的是把hold space内容放到pattern space以便s命令处理),然后用s命令删除所有换行符。实现二,和实现一相同,不过指定了-n选项,所以需要用p命令输出自己希望输出的东西。实现三使用g命令,与x命令不同的是g命令直接用hold space的内容覆盖pattern space的内容。
    2. 去掉所有空行空行是只包含空白字符的行。这个处理非常简单:如果当前pattern space中只包含空白字符,删除它就可以:
      1. hbwang@jcwkyl:/home/hbwang$sed -e "/^[ \t]*$/d" test  
      2. abc  
      3. de f  
      4. 1     2 345  
      5. en d  
      6. int main () {  
      7.     printf("hello\n");  
      8.     return 0;  
      9. }  
      10. last empty  
    3. 去掉多余的空行
      • 方法一:将连续多个空行变成一个,如果只有一个空行,则不变。有一个简单思路:如果当前行是空行,则删除当前行后续的所有连续空行。换一种描述:对所有的空行,删除其后续的所有连续空行。第二种描述更容易写出sed实现,因为sed基本功能就是“对什么样的行”进行“什么样的操作”。写出来的脚本如下:
        1. hbwang@jcwkyl:/home/hbwang$sed -e ‘/^[ \t]*$/{:a;N;s/^\([ \t]*\n\)\+/\1/;ta}‘ test  
        2. abc  
        3. de f  
        4. 1     2 345  
        5. en d  
        6.   
        7. int main () {  
        8.     printf("hello\n");  
        9.     return 0;  
        10. }  
        11.   
        12.   
        13. last empty  
        其中/^[ \t]*$/表示匹配空行,当从输入流中读取到一个空行时,就执行后面{}括起来的命令序列:继续从输入流中读取下一行,如果发现pattern space中是两个连续空行,则把这连续的两个空行替换成一个空行。
      • 方法二:像冒泡排序算法那样,将相邻的两个空行替换成一个空行。实现:
        1. hbwang@jcwkyl:/home/hbwang$sed -e ":a; N; s/\n\([ \t]*\n\)\1/\n\1/g; ba" test  
        2. abc  
        3. de f  
        4. 1     2 345  
        5. en d  
        6.   
        7. int main () {  
        8.     printf("hello\n");  
        9.     return 0;  
        10. }  
        11.   
        12. last empty  
        如果不清楚这条sed命令是如何完成任务的,可以使用l命令输出每次执行s命令前的pattern space中的内容,以理解s命令为什么写成那样:
        1. hbwang@jcwkyl:/home/hbwang$sed -n -e ":a ; N; l 200; ba" test  
        2. abc\nde f$ <===执行到N时,pattern space中是abd$,执行命令N后,pattern space中是abd\nde f$  
        3. abc\nde f\n1     2 345$  
        4. abc\nde f\n1     2 345\nen d$  
        5. abc\nde f\n1     2 345\nen d\n$  
        6. abc\nde f\n1     2 345\nen d\n\n$  
        7. abc\nde f\n1     2 345\nen d\n\n\n$  
        8. abc\nde f\n1     2 345\nen d\n\n\n\n$  
        9. abc\nde f\n1     2 345\nen d\n\n\n\n\nint main () {$  
        10. abc\nde f\n1     2 345\nen d\n\n\n\n\nint main () {\n    printf("hello\\n");$  
        11. abc\nde f\n1     2 345\nen d\n\n\n\n\nint main () {\n    printf("hello\\n");\n    return 0;$  
        12. abc\nde f\n1     2 345\nen d\n\n\n\n\nint main () {\n    printf("hello\\n");\n    return 0;\n}$  
        13. abc\nde f\n1     2 345\nen d\n\n\n\n\nint main () {\n    printf("hello\\n");\n    return 0;\n}\n$  
        14. abc\nde f\n1     2 345\nen d\n\n\n\n\nint main () {\n    printf("hello\\n");\n    return 0;\n}\n\n$  
        15. abc\nde f\n1     2 345\nen d\n\n\n\n\nint main () {\n    printf("hello\\n");\n    return 0;\n}\n\n\nlast empty$  
        以上,"l 200"表示以raw format输出pattern space的内容,200指定一行输出200个字符。
      • 方法三:和方法一类似,比方法一更简单的实现:
        1. hbwang@jcwkyl:/home/hbwang$sed -e "/^[[:blank:]]*$/{h; s/.*//; :a; N; s/^\n[[:blank:]]*$//; ta; s/^\n//; H; x;}" test  
        2. abc  
        3. de f  
        4. 1     2 345  
        5. en d  
        6.   
        7. int main () {  
        8.     printf("hello\n");  
        9.     return 0;  
        10. }  
        11.   
        12. last empty  
        这里用POSIX标准的方括号表达式[:blank:]表示空格和制表符,和方法一相同,当读到一个空行时,就执行后面的命令序列:首先把读取到的空行原样保存到hold space中去(h命令的作用),然后s/.*//命令用来清空pattern space中的内容(GNU版本的sed另外提供了z命令来清空pattern spac),N在pattern space中append一个换行符然后从输入流中读取下一行append到pattern space,s/^\n[ \t]*$//命令用来删除空行(因为N命令会在append下一行前先在pattern space中append一个换行符,所以s命令中匹配了换行符),如果替换成功,说明方才N命令读取的确实是一个空行,则用t命令跳转到label a去循环执行以删除空行。如果替换失败,则表示N命令读取到了一个非空行,则先去掉pattern space的第一个换行符(这个换行符是被N命令自动添加的),然后用H命令将pattern space中的内容append到hold space,最后用x命令把hold space中的内容放到pattern space做为最终的处理结果,这里的x命令也可以用g命令。

 

 

sed 

  sed命令是隐性的全局命令

参数s:替换文字内字符串。最多与两个地址参数配合。

1.在包含字符串test的任意行上,将111替换成222
#sed ‘/test/s/111/222/g‘  sample.txt  

2.以下三个命令相等,先在包含字符串test的任意行上,将111替换成222,再将字符f替换成hello
#sed ‘/test/s/111/222/g ; s/f/hello/g‘ sample.txt
#sed -e ‘/test/s/111/222/g‘ -e ‘s/f/hello/g‘ sample.txt
将要执行的所以编译命令放入在文件中
#more scher
/test/s/111/222/g
s/f/hello/g‘ sample.txt
#sed -f scher sample.txt

3.替换每行的第N个匹配(示例为替换第八个字符)
#sed ‘s/test/TEST/8‘ sample.txt

4在第三到第五行前加入hello
#sed ‘3,5 s/^/hello/‘ sample.txt

参数d: 删除数据行。最多与两个地址参数配合。
1.删除第一到三行
#sed ‘1,3d’sample.txt

2.删除带user的行
#sed ‘/user/d’sample.txt

3.删除带有a或b字符的行
#sed ‘/[ab]/d‘ sample.txt

参数a:将资料添加到指定文件后。最多与一个地址参数配合。
1.在含有FTP的行后面插入一行123
#sed -e ‘/FTP/a\123‘ sample.txt

2.在第五行后插入123
#sed -e ‘5 a\123‘ sample.txt

参数i将资料插入到指定文件前。最多与一个地址参数配合。
1.在含有FTP的行前面插入一行123
#sed -e ‘/FTP/i\123‘ sample.txt

2.在第五前后插入123
#sed -e ‘5 i\123‘ sample.txt


参数c:改变文件中的数据。最多与两个地址参数配合。
1.以使用者输入的数据取代数据
eg:将文件1到100行的数据替换成test
#sed -e ‘1.100c test‘ sample.txt

2.把a和b替换成hello
#sed ‘/[a b]/c\hello‘ sample.txt   

参数p:打印出资料。最多与两个地址参数配合。
1.打印出含有a或b的行
#sed -n -e ‘/[ab]/p‘ sample.txt

参数r:读入他的档案内容到文件中。最多与一个地址参数配合。
1.将temp.txt中的内容,搬至文件中含有AA字符串的数据行后(temp.txt中有内容)
#sed -e ‘/AA/r temp.txt‘ sample.txt

参数w:读入文件中的内容存入到另一文件中(temp.txt)。最多与一个地址参数配合。
1.将文件中含test字符串的数据行,copy至temp.txt档中储存(原temp.txt中无内容)
#sed -e ‘/test/w temp.txt‘ sample.txt

参数y:转换数据中的字符。最多与两个地址参数配合。
1.将文件中的小写字母替换成大写字母。
#sed -e ‘y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/‘ sample.txt
其中前后字符个数必须相同.

参数!:表示不执行函数参数。
1.将文件中除了important字符串,其余全删除。
#sed -e ‘/important/!d‘ sample.txt

参数n:表示读入下一行数据。最多与两个地址参数配合。
解释:例如源文件为:
A
B
C
D
那么实际读入到pattern space的数据就为B D,因为他们分别为第一行A和第三行C的下一行.
1.输出源文件的偶数行数据。
#sed -n -e ‘n‘ -e ‘p‘ sample.txt
或#sed -n ‘n;p‘ sample.txt
这里-n是选项。‘’中的n才是参数。-n的意思是将数据输出的控制权转给指令,即只显示处理后的结果。
利用n将下一行资料(即:偶数行)取代pattern space的资料行(奇数行)
2.输出源文件的奇数行数据。
#sed -n -e ‘p‘ -e ‘n‘ sample.txt
#sed -n ‘p;n‘ sample.txt

参数q:表示跳离sed。最多与一个地址参数配合。
1.打印出含有a或b字符的行,一旦遇到数字,即刻停止打印。
#sed -n -e ‘/[0-9]/q‘ -e ‘/[a b]/p‘ sample.txt

参数=:表示印出资料的行数。最多与两个地址参数配合。
1.印出文件资料中的行数。
#sed -e ‘=’ sample.txt

参数#:表示对文字的注释。

参数N:表示添加下一笔资料到pattern space内。最多与两个地址参数配合。(添加下一笔:添加一笔资料后,继续添加这个资料的下一行数据到pattern space内)
1,将文件中的数据合并。文件内容如下:
UNIX
LINUX
#sed -e ‘N‘ -e‘s/\n/\,/g‘ sample.txt
结果如下:
UNIX,LINUX

参数D:表示删除pattern space内的第一行资料。最多与两个地址参数配合。

参数P:打印出pattern space内的第一行资料。
#sed -n -e ‘N‘ -e ‘P‘ sample.txt
利用N将下一行资料(即:偶数行)添加到pattern space内,在利用P打印出奇数行。
解释过程:由于N的作用,使得每次添加一条资料到pattern space后,先不执行操作,而是继续添加这个资料的下一行到pattern space内,
然后P参数打印出第一行资料。


参数h:表示暂存pattern space的内容至hold space(覆盖)。最多与两个地址参数配合。

参数H:表示暂存pattern space的内容至hold space(添加)。最多与两个地址参数配合。

参数g:表示将hold space的内容放回至pattern space内。(覆盖掉原pattern space内的数据)

参数G:表示将hold space的内容放回至pattern space内。(添加大到原pattern space数据之后)
1.将文件中所有空行删除,并在每一行后面增加一个空行。
sed ‘/^$/d;G‘ sample.txt
2.将文件中所有空行删除,并在每一行后面增加两个空行。
sed ‘/^$/d;G;G‘ sample.txt

参数x:表示交换hold space与pattern space内的数据。
1.将文件第三行的数据替换成第一行的数据。
#sed -e ‘1h‘ -e ‘3x‘ sample.txt

参数b:

参数t:


一些示例:
1.在匹配式样test的行之前插入一空行。
#sed ‘/test/i\ ‘ sample.txt
#sed ‘/test/{x;p;x}‘ sample.txt

2.在匹配式样test的行之后插入一空行。
#sed ‘/test/a\ ‘ sample.txt
#sed ‘/test/G‘ sample.txt

3.为文中每一行进行编号。
#sed = sample.txt | sed ‘N;s/\n/:/‘
#sed = sample.txt | sed ‘N;s/\n/\t/‘

4.为文中每一行进行编号,但只显示非空行的编号。
#sed /./= sample.txt | sed ‘/./N;s/\n/:/‘
.不匹配空。将sample.txt中所有非空行编号,然后取出不包含非空行的行及其下一行数据放入pattern space内,再将空格替换成:)

5.计算文件行数。
#sed -n ‘$=‘ sample.txt

6.字串翻转。
#sed ‘/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//‘

7,打印文档奇数行。
#sed ‘n;d‘
#sed ‘x;$!N;x‘
#sed -n ‘p;n‘    (sed  -n -e ‘p‘ -e ‘n‘ )
#sed -e  ‘n‘ -e ‘d‘ 将文件下一行(偶数行),放进pattern space中并删除。

8.打印文档偶数行。
#sed ‘1d;n;d;‘  (先删掉第一行,再像奇数行类似处理)
#sed -n ‘n;p‘    (sed -n -e ‘n‘ -e ‘p‘)

9.删除连续重复行。(可以用sort加uniq取代)
#sed ‘$!N; /^\(.*\)\n\1$/!P; D‘

10.合并上下两行并用空格分割
#sed ‘$!N;s/\n/ /‘
#sed -e ‘N‘ -e ‘s/\n/ /g‘

11.将以\符号结尾的行与下行合并并以空格分隔(拼接断行)
#sed -e :a -e ‘/\\$/N; s/\\\n/ /; ta‘

12.按关键字拼接行。
如果某行以=开始,则合并到上一行并替代=为空格
#sed -e :a -e ‘$!N;s/\n=/ /;ta‘ -e ‘P;D‘

13.输出匹配行的下一行 (grep -A)
#sed -n ‘/regexpr/{n;p;}‘ filename

14.显示匹配行的行号并输出匹配行的上行、匹配行、下行 (grep -N N为想显示的行数)
#sed -n -e ‘/regexpr/{=;x;1!p;g;$!N;p;D;}‘ -e h

15.删除文档中某标志区域内的关键字匹配行
 删除文档中从being开到end结束的块中包含myword的行
#sed ‘/^begin/,/^end/{/myword/d;}‘ filename

16.字串解析。
1.从字串中解析出两个子串(前2各字符和后9个字符)
#echo "WeLoveChinaUnix"|sed -e ‘H;s/\(..\).*/\1/;x;s/.*\(.\{9\}\)$/\1/;x;G;s/\n/ /‘
We ChinaUnix
2.分解日期串
echo 20030922|sed ‘s/\(....\)\(..\)\(..\)/\1 \2 \3/‘|read year month day
echo $year $month $day
2003 09 22
例如想把aaaa1111bbbb分成 aaaa 1111 bbbb
sed ‘s/\(....\)\(....\)\(....\)/\1 \2 \3/‘ sample.txt
\1 \2中间的部分就是想空出来的部分。

示例部分参考http://bbs.chinaunix.net/viewthread.php?tid=166936&extra=&page=1
作者:admirer

补:
sed ‘/aaa/,/bbb/s/yes/no/‘ sample.txt
将文件sample.txt中,一行中的aaa到bbb中间的yes替换成no

 

 

 

 

1.sed


[root@stu93 sed]# sed -r ‘/\n!G;s/(.)(.*\n)/&\2\1;//D;s/.//‘ abc.txt 
回去查
流编辑器 stream editer,是以行为单位的处理程序


sed 流编辑器 stream editer


语法
   sed [options] ‘command‘ in_file[s]
options 部分
-n 阻止输入行自动输出
-e
-i
-f 脚本文件
-r 支持拓展正则
command 部分
‘[地址1,地址2] [函数] [参数(标记)]‘

定址的方法 1.数字 2.正则
数字
  十进制数
1 单行   
1,3 范围 从第一行到第三行
2,+4 匹配行后若干行
4,~3   从第四行到下一个3的倍数行
2~3 第二行起每间隔三行的行
$ 尾行
1! 除了第一行以外的行
2.sed  -n ‘‘ /etc/passwd 阻止输入行自动显示
3.sed -n  ‘p‘ /etc/passwd
4.‘cmd‘
定址 函数[标记];函数
5. [root@stu93 ~]# sed  -n ‘1{p;p}‘ /etc/passwd
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
[root@stu93 ~]# sed  -n ‘1p;3p‘ /etc/passwd
[root@stu93 ~]# sed -n ‘/^id/s/[0-6]/3/p‘ /etc/inittab 
id:3:initdefault:
6 [root@stu93 ~]# cat -n /etc/passwd | sed ‘6,~3p‘倍数行
[root@stu93 ~]# cat -n /etc/passwd | sed ‘6,+3p‘重复行
[root@stu93 ~]# cat -n /etc/passwd | sed ‘6~3p‘间隔行
[root@stu93 ~]# cat -n /etc/passwd | sed ‘6p‘指定行
[root@stu93 ~]# cat -n /etc/passwd | sed ‘6!p‘除了6行
[root@stu93 ~]# cat -n /etc/passwd | sed ‘$p‘最后一行
[root@stu93 ~]# sed -n ‘/root\|seker/p‘ /etc/passwd  含root和seker的行
[root@stu93 ~]# sed -n ‘/^root/,/^adm/p‘ /etc/passwd 以root和adm开头的行
[root@stu93 sed]# sed  ‘2c xyz.txt‘ abc.txt
aaaaaaaaaaa
xyz.txt
ccccccccccc


7. 基本正则
正则介绍


 ^ 行首
 $ 行尾
 . 除了换行符以外的任意单个字符
 * 前导字符的零个或多个
 .* 所有字符贪婪性取多不取少
 [] 字符组内的任一字符
 [^] 对字符组内的每个字符取反(不匹配字符组内的每个字符)
 ^[^] 非字符组内的字符开头的行
 [a-z] 小写字母
 [A-Z] 大写字母
 [a-Z] 小写和大写字母
四则运算 [+ - * /]不可以 [- + * /]减号方前面就可以了
 [0-9] 数字
 \< 单词头 单词一般以空格或特殊字符做分隔,连续的字符串被当做单词
 \> 单词尾

. 匹配除换行符职位的任意单个字符,awk中可以匹配换行符
* 匹配任意一个(包括零个)在它前面的字符
[...] 匹配方括号中的任意一个字符,^为否定匹配, -表示字符的范围
^ 作为正则表达式的第一个字符,匹配行的开始。在awk中可以嵌入换行符
$ 作为正则表达式的最后一个字符,匹配行的结尾。在awk中可以嵌入换行符
\{n,m\} 匹配出现的n到m次数, \{n\}匹配出现n次。\{n,\}匹配至少出现n次
\ 转义字符
\< \>单词
sed ‘/正则/‘
8. 扩展正则
sed -r ‘拓展正则‘
grep -E
egrep
grep \
+ 匹配前面的正则表达式的一次出现或多次出现
? 匹配前面的正则表达式的零次出现或一次出现
| 可以匹配前面的或后面的正则表达式(替代方案)
() 对正则表达式分组
{n,m} 匹配出现的n到m次数, {n}匹配出现n次。{n,}匹配至少出现n次,大多数awk都不支持,用于POSIX egrep和POSIX awk

[root@stu93 ~]# cat 4
egg
cow
[root@stu93 ~]# sed -e ‘s/egg/cow/‘ -e ‘s/cow/pig/ ‘ 4
pig
pig

[root@stu93 ~]# sed -e ‘s/cow/pig/‘ -e ‘s/egg/cow/‘  4
cow
pig
此时应该考虑顺序问题 可以变换下替换顺序
扩展正则 加 -r 参数 或转义
 sed -n ‘/roo\?/p‘ /etc/passwd  
 sed -rn ‘/roo?/p‘ /etc/passwd
 ? 前导字符零个或一个
 + 前导字符一个或多个
 abc|def abc或def
 a(bc|de)f abcf 或 adef
 x\{m\}   x出现m次
 x\{m,\}  x出现m次至多次(至少m次)

 x\{m,n\} x出现m次至n次

 


函数
增删改
 a\ 后插
 c\ 替换
 i \前插
 d 删除
这些命令每一个都要求后面加一个反斜杠用于转义第一个行尾
输入输出
 p 打印匹配的行 一般和 -n 参数连用,以屏蔽默认输出
 r 从文件中读入
 w 写入到文件中
y 字符替换(变形)
q 退出
控制流
 !  命令取反 例: 1!d 删除第一行以外的行
 {} 命令组合 命令用分号分隔 {1h;G} 可以理解为 -e 参数的另一种写法


 =  打印行号(输入行的号码,而非处理的次数行号) 例如: sed -n ‘2{=;p}‘ infile
 n  读入下一行到模式空间 例:‘4{n;d}‘ 删除第5行
 N  是追加下一行到模式空间,再把当前行和下一行同时应用后面的命令
 R 两个文件个行输出
 r 输出一行之后另个文件全不输出之后再输出前一个文件的另一行
 c
 i 对内存操作
P 输出当前模式空间中匹配的第一部分(第一个字符到第一个换行符为止)
D 从第一个字符删除到第一个换行符结束 它不会导入新的输入行 而是返回输入行顶部继续执行
[root@stu93 ~]# sed -n ‘s/root/ABCDEF/gp‘ /etc/passwd

ABCDEF:x:0:0:ABCDEF:/ABCDEF:/bin/bash
operator:x:11:0:operator:/ABCDEF:/sbin/nologin


[root@stu93 ~]# sed -n ‘s/root/ABCDEF/2p‘ /etc/passwd
root:x:0:0:ABCDEF:/root:/bin/bash
[root@stu93 ~]# sed -n ‘s/root/ABCDEF/3p‘ /etc/passwd
root:x:0:0:root:/ABCDEF:/bin/bash
[root@stu93 ~]# sed -n ‘s/root/ABCDEF/gp‘ /etc/passwd
ABCDEF:x:0:0:ABCDEF:/ABCDEF:/bin/bash
operator:x:11:0:operator:/ABCDEF:/sbin/nologin

[root@stu93 ~]#cat a.txt
123
123
123  
[root@stu93 ~]#sed -r ‘$!N; /^(.*)\n\1$/!P;D‘ a.txt
123
高级命令
NDP sed -r ‘$!N;/^(.*)\n\1$/!p;D‘
[root@stu93 ~]# cat a
this is the unix
system and unix is like the
unix system
[root@stu93 ~]# sed ‘N;s/\n/‘‘/;s/ system/ opting system/;P;D‘ a
this is the unix opting system and unix is like the
unix opting system

替换
 s 字符串替换 s/old/new/

$ sed -n ‘s/root/ABCDEF/p‘ /etc/passwd

ABCDEF:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/ABCDEF:/sbin/nologin

定址
[root@stu93 ~]# cat a.txt 
beijing ,chain
shanghai ,chain
aaa
tianjin .chain
bbb chengdu .chain [root@stu93 ~]# sed ‘/^aaa/,/^bbb/{s/tianjin/TJ/;s/chain/CN/}‘ a.txt  beijing ,chain shanghai ,chain aaa TJ .CN bbb chengdu .chain [root@stu93 sed]# sed -n ‘1,3s/root/AA/gp‘ passwd AA:x:0:0:AA:/AA:/bin/bash [root@stu93 ~]# sed ‘=‘ /etc/passwd | sed ‘N;s/\n/ /‘ 每两行处理为一行 三行处理成一行 [root@stu93 ~]# cat b.txt  2010-09-23 192.168.0.1 shutdown 2010-09-22 192.168.0.2 reboot 2010-09-24 192.168.0.3 init 0 [root@stu93 ~]#  sed ‘N;N; s/\n/ /g‘ b.txt 2010-09-23 192.168.0.1 shutdown 2010-09-22 192.168.0.2 reboot 2010-09-24 192.168.0.3 init 0 连着的多个空行变为一个空行输出 [root@stu93 ~]# cat c.txt  1111111 3333 666666666 100000000 [root@stu93 ~]# sed ‘/^$/{N; /^\n$/D }‘ c.txt  D 删除第一个空行 [root@stu93 ~]# sed ‘/^$/d;$!G‘ c.txt      $!G表示最后一行不执行G规则 1111111 3333 666666666 100000000 [root@stu93 ~]# time sed ‘2q‘ a.txt   q 对大文件操作较快 [root@stu93 ~]# time sed -n ‘1,2p‘ a.txt 对小文件可以 \(\) 保存被匹配的字符 以备反向引用\N时使用 最多9个标签 标签顺序从左至右 & 替换时使用,在不定义标签时使用(反向引用) 试做:     删除第一个单词 删除最后一个单词 将第一个单词和最后一个单词兑换位置 y 字符替换(变形) 工作模式 模式空间和保持空间介绍 [root@stu93 ~]# sed  ‘1{p;p}‘ a.txt 11111111 11111111 11111111 22222222 33333333 44444444 55555555 66666666 置换 模式空间和保持空间(暂存空间)  h 把模式空间内容覆盖到保持空间中  H 把模式空间内容追加到保持空间中  g 把保持空间内容覆盖到模式空间中  G 把保持空间内容追加到模式空间中  x 交换模式空间与保持空间的内容 [root@stu93 ~]# cat test.sh  1111111 2222222 3333333 4444444 [root@stu93 ~]# sed  ‘{1h;2,3H;4G}‘  ./test.sh  1111111 2222222 3333333 4444444 1111111 2222222 3333333 [root@stu93 ~]# sed  ‘{1h;2x;3g;$G}‘  ./test.sh  1111111 1111111 2222222 4444444 2222222 #  [root@stu93 sed]# sed ‘1H;2,3{G};$g‘ xyz.txt  1111111 2222222 1111111 3333333 1111111 1111111 [root@stu93 sed]# sed ‘1h;2,3H;$!G‘ xyz.txt  1111111 1111111 2222222 1111111 2222222 3333333 1111111 2222222 3333333                                                                                                                                                                                                                                                                                                                                                                                                       4444444 cmd qianhou sed null\n 1h 11111111 $!G 1111  11111111 ==>1111  1111 2H 22221111 2222 $!G 2222 1111 2222       11112222 ==>2222 1111 2222 3H 33331111 2222 3333 $!G 3333 1111 2222 3333 ==>3333 1111 2222 3333 $!G 4444 [root@stu93 sed]# tac xyz.txt  4444444 3333333 2222222 1111111 [root@stu93 sed]# sed ‘4G;2,3{G;h;d};1{h;d};‘ xyz.txt  [root@stu93 sed]# sed ‘4G;3{G;h;d};2{G;h;d};1{h;d};‘ xyz.txt  4444444 3333333 2222222 1111111 4G 44444/n/n =>4444/n 3{G;h;d} 3333 /n 3333 3333 3333 ==>3333 2{G;h;d} 2222 2222 2222 2222 ==>2222 1{h;d} 1111 1111 1111 ==>1111 [root@stu93 sed]# sed  ‘1!G;h;$!d‘ xyz.txt 试做题 奇数行和偶数行互换 [root@stu93 ~]# cat 3 .txt 1 2 11 22 111 222 [root@stu93 ~]# sed -e ‘/1/{h;d}‘ -e ‘/2/{G}‘ 3.txt 每行的后面加空行 [root@stu93 ~]# sed ‘G‘ 3.txt 每行的后面加2个空行 [root@stu93 ~]# sed ‘G;G‘ 3txt 显示文件的前10行 [root@stu93 ~]# sed -n ‘1,10p‘ /etc/passwd 每行的前面加空行 [root@stu93 ~]# sed  -e ‘x;P;x‘  3.txt 将第一行插入到每个偶数行的后面 $ sed  ‘1h;0~2G‘ a.txt 11111111 22222222 11111111 33333333 44444444 11111111 55555555 66666666 11111111 $ 颠倒输出 [root@stu93 ~]#  sed ‘1!G;h;$!d‘ rev.txt [root@stu93 ~]# sed -n ‘1!G;h;$p‘ 3 xyz def abc 脚本方法 四 编写sed脚本 模式空间 sed   -e  ‘s/pig/cow/’ -e ‘s/cow/horse/’ sed   -e ‘s/cow/horse/’ -e ‘s/pig/cow/’   寻址上的全局透视 全局操作   范例file2.txt $ sed ‘/Beijing/s/CN/China/g‘ file2.txt 删除所有的行 d 删除文件的最后两行 [root@stu93 ~]# sed ‘N;$!P;$!D;$d‘ c.txt  只删除第一行 1d 使用寻址符号$,删除最后一行 $d 删除空行,正则表达式必须封闭在斜杠//当中 /^$/d 删除.TS和.TE标记的tbl输入 /^\.TS/,/^\.TE/d 删除第五行到结尾所有的行 5,$d 混合使用行地址和模式地址 $ sed ‘1,/^$/d‘ file2.txt 删除除了那些行以外的行 1,5!d 分组命令 /^\.TS/,/^\.TE/{       /^$/d } /^\.TS/,/^\.TE/{ /^$/d   s/^\.ps 10/.ps 8/   s/^\.vs 12/.vs 10/ }      -f 参数 引用脚本(脚本的末尾不能有空格制表符或其他文本) # cat sed.sh  2,4d s/777/seker/ s/999/seker&seker/ # sed -f sed.sh test.txt  1111111 5555555 6666666 seker7777 8888888 seker999seker9999 #   在脚本中指明解释器为sed # cat sed.sh  #!/bin/sed -f 2,4d s/777/seker/ s/999/seker&seker/ # ./sed.sh test.txt  1111111 5555555 6666666 seker7777 8888888 seker999seker9999 #  高级流控命令 b分支 t测试 分支命令用于无条件转移,测试命令用于有条件转移 分支 branch    跳转的位置与标签相关联 如果有标签则跳转到标签所在的后面行继续执行 如果没有标签则跳转到脚本的结尾处.    标签 以冒号开始后接标签名 不要在标签名前后使用空格 跳转到标签指定位置 :top   cmd1   cmd2 /aa/b top cmd3 cmd1 /aa/b end cmd2 :end cmd3 cmd1 /aa/b dothree cmd2 b :dothree cmd3 [root@stu254 ~]# grep seker /etc/passwd seker:x:500:500::/home/seker:/bin/bash [root@stu254 ~]# [root@stu254 ~]# grep seker /etc/passwd |sed ‘:top;s/seker/blues/;/seker/b top;s/5/555/‘  blues:x:55500:500::/home/blues:/bin/bash [root@stu254 ~]#  命令分析:让单次替换(cmd1)循环执行,直到条件不满足 :top; 定义一个top标签 s/seker/blues/; cmd1 /seker/b top; 如果模式匹配则跳转到top标签 s/5/555/ 当上一条模式不匹配时,既会继续执行这一条 选择执行 [root@stu254 ~]#  grep ‘seker‘ /etc/passwd |sed ‘s/seker/blues/;/seker/b end;s/5/555/;:end;s/5/666/‘ blues:x:66600:500::/home/seker:/bin/bash [root@stu254 ~]#  zorro:x:501:501::/home/zorro:/bin/bash [root@stu254 ~]#  grep ‘zorro‘ /etc/passwd |sed ‘s/seker/blues/;/seker/b end;s/5/555/;:end;s/5/666/‘ zorro:x:6665501:501::/home/zorro:/bin/bash [root@stu254 ~]#  命令分析: 执行cmd1,再去模式匹配,成功则跳转到cmd3开始执行,否则(模式不匹配)会按命令顺序逐个执行 s/seker/blues/; cmd1 /seker/b end; s/5/555/; cmd2 :end; s/5/666/ cmd3 另一种选择执行 [root@stu254 ~]#  grep ‘seker‘ /etc/passwd |sed ‘s/seker/blues/;/seker/b end;s/5/555/;b;:end;s/5/666/‘ blues:x:66600:500::/home/seker:/bin/bash [root@stu254 ~]#  grep ‘zorro‘ /etc/passwd |sed ‘s/seker/blues/;/seker/b end;s/5/555/;b;:end;s/5/666/‘ zorro:x:55501:501::/home/zorro:/bin/bash [root@stu254 ~]#  命令分析: 执行cmd1;模式匹配cmd2成功则执行cmd3;否则执行cmd2,再跳转到脚本末尾  s/seker/blues/; cmd1 /seker/b end; s/5/555/;  cmd2 b; :end; s/5/666/ cmd3 测试命令,如果前一个替换命令执行成功则跳转到脚本末尾 (case结构) [root@stu254 ~]#  grep ‘seker‘ /etc/passwd |sed ‘s/seker/ABC/;t;s/home/DEF/;t;s/bash/XYZ/‘ ABC:x:500:500::/home/seker:/bin/bash [root@stu254 ~]#  grep ‘zorro‘ /etc/passwd |sed ‘s/seker/ABC/;t;s/home/DEF/;t;s/bash/XYZ/‘ zorro:x:501:501::/DEF/zorro:/bin/bash [root@stu254 ~]# 与标签关联,跳转到标签位置 [root@stu254 ~]#  grep ‘seker‘ /etc/passwd |sed ‘s/seker/ABC/;t end;s/home/DEF/;t;:end;s/bash/XYZ/‘ ABC:x:500:500::/home/seker:/bin/XYZ [root@stu254 ~]#    [seker@seker ~]$ grep ‘zorro‘ /etc/passwd |sed ‘s/seker/ABC/;t end;s/home/DEF/;t;:end;s/bash/XYZ/‘ zorro:x:501:501::/DEF/zorro:/bin/bash [seker@seker ~]$ runsed 对输入文件作永久性改变 #!/bin/bash         for x do         echo "editing $x: \c"         if test "$x" = sedscr;then         echo "not editing sedscript"         elif test -s $x;then         sed -f sedscr $x > /tmp/$x$$         if test -s /tmp/$x$$         then                 if cmp -s /tmp/$x$$                 then                         echo "file not changed: \c"                 else                         mv $x.bak # save original, just in case                         cp /tmp/$x$$ $x                 fi                 echo "done"                 else                 echo "Sed produced an empty file\c"                 echo "- check your sedscript."         fi         rm -f /tmp/$x$$         else                 echo "original file is empty."         fi         done         echo "all done"

 

 

 

 

sed学习总结

(2012-03-30 18:42:11)

 

标签:

杂谈

分类: linux

 

| s | d | a | i | c | p | l | r | w | y | ! | n | q | = | # | N | D | P | h | H | g | G | x | b | t | 
s
 函数参数 s 表示替换(substitute)文件内字串。其指令格式如下:[address1[ ,address2]] s/pattern/replacemen/[flag].函数参数 s 最多与两个位址参数配合
 pattern : 它为 reguler expression 字串。它表示文件中要被替换的字串
 replacement : 它为一般字串。但其内出现下列字元有特别意义:
  & : 代表其前 pattern 字串。例如 sed -e ‘s/test/& my car/‘ 指令中 , & 代表 pattern 字串 "test"。故执行後 , 资料档的 "test" 被替换成 "test my car"
  \n : 代表 pattern 中被第 n 个 \( 、\)(参照[附录 A]) 所括起来的字串。例如sed -e ‘s/\(test\) \(my\) \(car\)/[\2 \3 \1]/‘ 指令中 , \1 表示 "test"、\2 表示 "my"、\1 表示 "car" 字串。故执行後 , 资料档的 "test my car" 被替换成 "[my car test]"
  \ : 可用它来还原一些特殊符号(如上述的 & 与 \ )本身字面上的意义 , 或用它来代表换行。 
 flag : 主要用它来控制一些替换情况:
  当 flag 为 g 时 , 代表替换所有符合(match)的字串
  当 flag 为十进位数字 m 时 , 代表替换行内第 m 个符合的字串
  当 flag 为 p 时 , 代表替换第一个符合 pattern 的字串後 , 将资料输出标准输出档
  当 flag 为 w wfile 时 , 代表替换第一个符合 pattern 的字串後 , 输出到 wfile 档内(如果 wfile 不存在 , 则会重新开启名为 wfile 的档案)
  当没有 flag 时 , 则将资料行内第一个符合 pattern 的字串以 replacement 字串来替换
 delimiter : 在 "/pattern/replace/[flag] " 中 "/" 被当成一 delimiter。除了空白(blank)、换行(newline) 之外,使用者可用任何字元作为 delimiter。例如下述编辑指令s#/usr#/usr1#g,上述命令中 \verb|#| 为 delimiter。如果用 "/" 做 delimiter , 则 sed 会将 pattern 与 replacement 中的 "/"当成 delimiter 而发生错误
 例:替换 input.dat 档内 "1996" 字串成 "1997" , 同时将这些资料行存入 year97.dat 档内
 说明:用函数参数 s 指示 sed 将 "1996" 字串替换成 "1997" , 另外用 s argument 中的 flag w 指示sed将替换过的资料行存入 year97.dat 档内
 sed -e ‘s/1996/1997/w year97.dat‘ input.dat
  
 语法格式
  s/Regexp/Replacement/Flags
  分隔字符/可以用其他任意一个单字符代替,若在Regexp或Replacement中有分隔字符,必须要进行转义操作。
 功能说明
  命令s可能是sed最重要的命令,基本功能就是:用指定的Regexp试图匹配模版空间中的数据,若成功,就用指定的Replacement替换模版空间中匹配的部分。
 替换选项说明
  1、\n
   替换正则表达式Replacement中可含有后向引用中的\n(n是1至9),引用前面定义的子表达。
  2、&
   代表模版空间中的整个匹配部分。
  3、\L GNU的扩展功能
   将在其后的替换部分转换成小写字母,直到发现一个\U或\E。
  4、\l GNU的扩展功能
   将下一个字符转换成小写字母。
  5、\U GNU的扩展功能
   将在其后的替换部分转换成大写字母,直到发现一个\L或\E。
  6、\u GNU的扩展功能
   将下一个字符转换成大写字母。
  7、\E GNU的扩展功能
   停止由\L或\U指示开始的大小写转换。
   所以替换正则表达式Replacement中要含有字符\或&或字符串\n的本身,必须要进行转义操作,即变成:\\、\&和\\n的形式。
   注意:为什么在Replacement中不用重复元字符:\+、\?、\{、\}

 

d
 函数参数 d 表示删除资料行,其指令格式如下:[address1[ ,address2]] d 对上述格式有下面几点说明:函数参数 d 最多与两个位址参数配合
 sed 执行删除动作情况如下:将 pattern space 内符合位址参数的资料删除,将下一笔资料读进 pattern space重新执行 sed script
 删除命令,清空模版空间中的数据,立即开始sed 下一处理循环。

 


 函数参数 a 表示将资料添加到文件中。其指令格式如下: [address1] a\  使用者所输入的资料 对上述格式有下面几点说明:函数参数 a 最多与一个位址参数配合
 函数参数 a 紧接着 "\" 字元用来表示此行结束,使用者所输入的资料必须从下一行输入。如果资料超过一行 , 则须在每行的结尾加入"\"
 sed 执行添加动作情况如下 : 当 pattern space 内资料输出後 , sed 跟着输出使用者所输入的资料
 例:添加 "多工作业系统" 在含 "UNIX" 字串的资料行後。
 sed -e ‘/UNIX/a\
 多工作业系统
 ‘ input.dat 

 


 函数参数 i 表示将资料插入文件中。其指令格式如下:[address1] i\  使用者所输入的资料 对上述格式有下面几点说明:函数参数 i 最多与一个位址参数配合
 函数参数 i 紧接着 "\" 字元用来表示此行结束 , 使用者所输入的资料必须从下一行输入。如果资料超过一行 , 则须在每行的结尾加入"\"
 sed 执行插入动作的情况如下 : 在 pattern space 内资料输出前 , sed 先输出使用者所输入的资料
 例:将 "文章版权属於中央研究院" 插在 input.dat 档中含 "院长 : 李远哲" 的资料行之前
 sed 命令列如下:
 sed -e ‘/院长 : 李远哲/i\
 文章版权属於中央研究院
 ‘ input.dat

 


 函数参数 c 表示改变文件中的资料。其格式如下:[address1[ ,address2]]c使用者所输入的资料 对上述格式有下面几点说明:函数参数 c 最多与两个位址参数配合
 函数参数 c 紧接着 "\" 字元用来表示此行结束 , 使用者所输入的资料必须从下一行输入。如果资料超过一行 , 则须在每行的结尾加入"\"
 sed 执行改变动作的情况 : 在 pattern space 内资料输出时 , sed 改变它成为使用者所输入的资料

 


 显示命令,作用是显示模版空间的数据,通常和命令行选项-n 同时使用。
 常用在多个命令要对相同 sed 地址行进行处理时
 函数参数 p 表示印出资料。其指令格式如下:[address1[ , address2]] p 对上述格式有下面几点说明:函数参数 p 最多与两个位址参数配合
 sed 执行印出动作的情况如下 : sed 拷备一份 pattern space 内容至标准输出档
 

 函数参数 l , 除可将资料中的 nonprinting character 以 ASCII码列出外 , 其於均与函数参数 p 相同。例如 , 将下面 input.dat 档中的 ^[ 以 ASCII 码印出
 The Great ^[ is a movie starring Steve McQueen.
 执行命令 sed -e ‘l‘ input.dat 後 , 则输出结果如下:
 The Great \003 is a movie starring Steve McQueen.
 The Great is a movie starring Steve McQueen.
 上述第二行资料为 sed 的自动输出

 


 函数参数 r 表示读入它档案内容到文件中。其指令格式如下:[address1] r 它档名称 对上述格式有下面几点说明:函数参数 r 最多与一个位址参数配合
 在指令中 , 函数参数 r 与它档名称间 , 只能有一空格
 sed 执行读入动作的情况如下 : 在 pattern space 内资料输出後 , sed 读出它档的内容跟着输出。当它档不存在时,sed 照样执行其它指令而不会有任何错误讯息产生

 


 函数参数 w 表示将文件中的写到它档内。其指令格式如下:[address1[ ,address2]] w 它档名称 对上述格式有下面几点说明:函数参数 w 最多与两个位址参数配合
 在指令中 , 函数参数 w 与它档名称间 , 只能有一空格
 sed 执行写出动作的情况如 : 将 pattern space 内资料写到它档内。资料写入时 , 会取代(overwrite)原来档案内的资料。另外 , 当它档不存在时 , sed 会重新产生(creat)它

 


 函数参数 y 表示转换资料中的字元。其指令格式如下:[address1[ ,address2]]y /xyz.../abc.../  对上述格式有下面几点说明:函数参数最多配合两个位址参数
 指令中 , /abc.../xyz.../(x、y、z、a、b、c 代表某些字元) 为 y 的 argument 。其中 abc... 与 xyz... 的字元个数必须相同
 sed 执行转换时 , 将 pattern space 内资料内的 a 字元转换成 x 字元 、b 字元转换成 y 字元 、c 字元转换成 z 字元 ...。 

 


 函数参数 ! 表示不执行函数参数。当有如下指令时,[address1[ , address2]] ! 函数参数表示,对符合位址参数之资料不执行函数参数。例如删除,除了含 "1996" 字串,所有资料行,则执行如下命令sed -e ‘/1996/!d‘ input.dat
 

 函数参数 n 表示读入下一行资料。其指令格式如下:[address1[ ,address2]] n  对格式有下面几点说明:函数参数 n 最多配合两个位址参数
 sed 执行读入下一行动作的情况如下:输出在 pattern space 的资料,将下一笔资料读到 pattern space,执行下一个编辑指令。
 新行命令,作用是显示模版空间的数据(无选项-n时)后,sed立即读取新的一行来取代模版空间
 的数据,此时若没有待输入行了,sed直接退出,不再处理任何命令。
 例:输出 input.dat 档内偶数行资料。假设 input.dat 档内容如下:
 The
 UNIX
 Operation
 System
 说明: 在命令列上以选项 -n , 将资料输出的控制权转给指令,利用函数参数 n 将下一行资料(偶数行)取代 pattern space 内的资料行(奇数行),利用函数参数 p 将 pattern space 内的资料(偶数行)输出,最後 , 整个输出只有原先档内的偶数行资料
 sed 命令列如下:sed -n -e ‘n‘ -e ‘p‘ infro.dat
 执行上述命令後,输出的结果如下 :
 UNIX
 System
 

 函数参数 q 表示跳离 sed 。其指令格式如下:[address1] q 对上述格式有下面几点说明:函数参数 q 最多配合一个位址参数
 sed 执行跳离动作时 , 它停止输入 pattern space 资料 , 同时停止资料送到标准输出档
 退出命令,只接受单一匹配的sed地址。表示退出sed,不再处理任何命令或输入,若没有选项
 -n ,在退出前会显示当前模版空间中的数据。
 退出并返回指定的退出代码,是GNU的扩展功能。
 例 : 
 题目: 对文件档执行 script_file 内的编辑指令 , 除非遇到 "Linux" 字串
 sed 命令列如下:sed -e ‘/Linux/q‘ -f script_file input.dat

 


 函数参数 = 表示印出资料的行数。其指令格式如下: [address1 ,[address2]] =  对上述格式有下面几点说明:函数参数 = 最多配合两个位址参数
 执行时 , 行数将在资料输出前先输出
 例:印出 input.dat 档内资料行数。假设 input.dat 的内容如下:
 The UNIX
 Operating System
 说明:用函数参数 = 来印出资料的行数 sed 命令列如下: sed -e ‘=‘ input.dat
 执行上述命令後 , 输出的结果如下:
 1
 The UNIX
 2
 Operating System
 

 在 script file 内 , 函数参数 # 後的文字为注解。当注解文字超过多行时 , 其行间须以 "\" 换行字元相隔
 注释命令,不允许有sed地址。用于对sed脚本的注解和说明,此字符后内容即为注释直到行尾。 
 1、有些版本的sed只允许脚本有一行注释,且必须是第一行,即脚本的第一个字符必是# 。
 2、当sed脚本的前两个字符是#n时,表示强制打开选项-n (不自动显示);同时考虑上面要求,
 注释若是以#n开始的,必须改成#N或# n的形式。
 

 函数参数 N 表示添加下一笔资料在 pattern space 内。其指令格式如下:[address1 ,[address2]] N  对上述格式有下面几点说明:函数参数 N 最多配合两个位址参数
 sed 执行时 , 将下一行资料读入并添加在 pattern space 内 , 资料行间以换行字元(embedded newline character)分隔。此外 , 在替换时 , 换行字元可用 \n 来 match
 例:将下述两行资料合。假设 input.dat 的内容如下:
 The UNIX
 Operating System
 说明:先利用函数参数 N 将两行资料置於 pattern space内,再利用函数参数 s/\n/ / 将两行资料间的分隔号 \n 以空白替代 , 如此两行资料变成一行输出
 sed 命令列如下: sed -e ‘N‘ -e ‘s/\n/ /‘ input.dat

 


 函数参数 D 表示删除 pattern space 内的第一行资料。其指令格式如下:[address1,address2]D 对上述格式有下面几点说明:函数参数 D 最多配合两个位址参数
 函数参数 D 与 d 的比较如下:当 pattern space 内只有一资料行时 , D 与 d 作用相同。当 pattern space 内有多行资料行时D 表示只删除 pattern space 内第一行资料 ; d 则全删除。D 表示执行删除後 , pattern space 内不添加下一笔资料 , 而将剩下的资料重新执行 sed script ; d 则读入下一行後执行 sed script

 


 函数参数 P 表示印出 pattern space 内的第一行资料。其指令格式如下: [address1,address2] P  对上述格式有下面几点说明:函数参数 P 最多配合两个位址参数
 P 与 p , 除了面对的 pattern space 内的资料行数不同外 , 其它均相同
 例:输出 input.dat 档内奇数行资料。假设 input.dat 档内容如下:
 The
 UNIX
 System
 说明: 在命令列上以选项 -n , 将资料输出的控制权转给指令。利用函数参数 N 将偶数行添加至 pattern space 内奇数行後。利用函数参数 P 将 pattern space 内的第一行(奇数行)输出。在奇数行输出後 , pattern space 内剩下的资料行(偶数行)则被放弃输出。最後 , 整个输出只有原先的奇数行资料。
 sed 命令:sed -n -e ‘N‘ -e ‘P‘ infro.dat
 执行上述命令後 , 输出的结果如下:
 The
 System
 

 函数参数 h 表示暂存 pattern space 的资料至 hold space。其指令格式如下:[address1 ,[address2]] h  对上述格式有下面几点说明:函数参数 h 最多配合两个位址参数
 sed 执行暂存动作时 , 会盖掉(overwrite) hold space 内原来的资料,当 sed 全部执行结束时 , hold space 内资料会自动清除

 


 函数参数 H 与 h 唯一差别是 , sed 执行 h 时 , 资料盖掉(overwrite) hold space 内原来的资料 , 而 H , 资料则是 "添加(append)" 在 hold space 原来资料後。

 


 函数参数 g 表示与函数参数 h 相反的动作 , 它表示将 hold space 内资料放回 pattern space 内。其指令格式如下:[address1,address2]g 函数参数 g 最多配合两个位址参数
 sed 执行放回动作时 , 资料盖掉(overwrite)pattern space 内原来的资料

 


 函数参数 G 与 g 唯一差别是 , sed 执行 g 时 , 资料盖掉(overwrite) pattern space 内原来的资料 , 而 G , 资料则是 "添加(append)" 在 pattern space 原来资料後

 


 函数参数 x 表示交换 hold space 与 pattern space 内的资料。其指令格式如下: [address1 ,[address2]] x  函数参数 x 大部份与其它处理 hold space 的函数参数一起配合
 例如 , 将 input.dat 档内第 1 行资料取代第 3 行资料。此时 , 用函数参数 h 与 x 来配合。其中 , 以函数参数 h 将第 1 资料存入 hold space ; 当第 3 行资料出现在Pattern space , 以函数参数 x 交换 hold space 与 pattern space 的内容。如此 , 第 3 行资料就被第 1 资料替代
 其命令列如下:sed -e ‘1h‘ -e ‘3x‘ input.dat
 
b、:label 
 函数参数 : 与函数参数 b 可在 sed script 内建立类似 BASIC 语言中 GOTO 指令的功能。其中 , 函数参数 : 建立标记;
 函数参数 b 将下一个执行的指令 branch 到标记处执行。函数参数 : 与 b , 在 script file 内配合的情况如下 [address1,[address2]]b [记号] 
 如果指令中函数参数 b 後没有记号 , 则 sed 将下一个执行的指令 branch 到 script file 的最後
 例:将 input.dat 档内资料行的开头字母重覆印 40 次。假设 input.dat 档的内容如下:
 A
 B
 C
 说明: 用指令 b p1 与 :p1 构成执行增加字母的圈(loop) , 同时在字母出现 40 个时 , 也用指令 b 来跳出圈。下面就以档内第一行资料 "A" 为例 , 描述它如何连续多添加 39 个 "A" 在同一行:
 用指令 s/A/AA/将 "A" 替换成 "AA".用指令 b p1 与 :p1 构成圈(loop) , 它目的使上述动作被反覆的执行。每执行一次圈 , 则资料行上的 "A" 就多出一个。例如 , 第一次圈资料行变成 "AA" , 第二次圈资料行变成 "AAA" ...
 用指令 [ABC]\{40\}/b(解[15]) 来作为停止圈的条件。当资料行有连续 40 个 A 出现时 , 函数参数 b 将执行的指令跳到最後 , 停止对此行的编辑。同样 , 对其它资料行也如同上述的方式执行.
 sed 命令列如下:
 sed -e ‘{
 :p1
 /A/s/A/AA/
 /B/s/B/BB/
 /C/s/C/CC/
 /[ABC]\{40\}/b
 b p1
 }‘ input.dat

 


 基本上 , 函数参数 t 与 函数参数 b 的功能类似 , 除了在执行 t 的 branch 前 , 会先去测试其前的替换指令有没有执行替换成功外
 其中 , 与函数参数 b 不同处在於 , 执行函数参数 t branch 时 , 会先检查其前一个替换指令成功与否。如成功 , 则执行 branch ; 不成功 , 则不 branch , 而继续执行下一个编辑指令
 例将 input.dat 档中资料 A1 替换成 C1、C1 替换成 B1、B1 替换成 A1。input.dat 档的内容如下:
 代号
 B1
 A1
 B1
 C1 
 A1
 C1
 说明 : input.dat 档中全部资料行只需要执行一次替换动作 , 但为避免资料被替换多次, 使每行资料替换一次後能立即用函数参数 t 跳离替换编辑
 sed 命令列:
 sed -e ‘{
 s/A1/C1/
 t
 s/C1/B1/
 t
 s/B1/A1/
 t
 }‘ input.dat 

 

{ commands }
 组命令。作用是将多个命令用字符对( {} )括起来,形成一组命令。

 

\+ 与星号(*)相同,只是至少重复1次。是GNU的扩展功能
\? 与星号(*)相同,只是最多重复1次。是GNU的扩展功能
\{i\} 与星号(*)相同,只是重复指定的i次,i的值必须介于0至RE_DUP_MAX(含)之间。RE_ DUP_ MAX是POSIX定义的符号型常数,可通过getconf命令取得,最小值为255
\{i,j\} 与星号(*)相同,只是重复i至j次
\{i, \} 与星号(*)相同,只是至少重复i次
\(regexp\)  将regexp看作一个整体,用于:1、重复匹配中,如\(abc\)+匹配至少有一个整体abc的字符串;2、定义后向引用的子表达式
regexp1\|regexp2 用在相邻的正则表达式之间,表示匹配这些正则表达式中任一个都可以。匹配是从左向右开始的,一旦匹配就不再尝试下一个正则表达式。是GNU的扩展功能。
regexp1regexp2 匹配regexp1和regexp2的连接结果

 

GNU对转义字符的功能扩展
 编号 转义字符 功能说明
 1  \a 产生或匹配一个BEL字符,响铃作用,ASCII 7 。
 2  \f 产生或匹配一个换页字符,ASCII 12 。
 3  \n 产生或匹配一个换行字符,ASCII 10 。
 4  \r 产生或匹配一个回车字符,ASCII 13 。
 5  \t 产生或匹配一个水平Tab字符,ASCII 9 。
 6  \v 产生或匹配一个垂直Tab字符,ASCII 11 。
 7  \cX  产生或匹配Control-X,X是任意字符。精确结果是:若X是小写字母,就转成对应的大写字母。将X的ASCII值的第7bit位(从右向左)求反:\cz变为x1A,\c{变为x3B,\c;变为x7B
 8  \dXXX 产生或匹配一个ASCII码是十进制XXX的字符。
 9  \oXXX 产生或匹配一个ASCII码是八进制XXX的字符。
 10  \xXX 产生或匹配一个ASCII码是十六进制XX的字符。
 11  \w 匹配任意一个单词字符(字母、数字和下划线)。
 12  \W 匹配任意一个非单词字符。
 13  \b 匹配一个单词的边界符:字符的左边是一个单词字符,并且右边是一个非单词字符,反之亦然。???????
 14  \B 匹配除单词边界符外所有字符:字符的左边和右边同时是单词字符或非单词字符。???????
 15  \` 匹配模版空间的开头,在多行模式时,不同于字符^。???????
 16  \’ 匹配模版空间的结束,在多行模式时,不同于字符$。??????

 

sed脚本中的地址形式,sed的地址用于sed命令的前面,表示只有符合指定地址条件的行才能执行后面的命令
1、NUMBER(单一匹配) 只匹配指定号行NUMBER的那一行
2、FIRST~STEP(递增匹配) GNU的扩展功能 匹配从起始行FIRST (含)开始,以后行号每增加STEP的正整数倍,就是匹配行。比如要匹配所有奇数行就用1~2即可
3、$(尾行匹配) 匹配最后一个输入文件的最后一行;若有选项-i或-s则匹配每个输入文件的最后一行
4、/REGEXP/(正则表达式匹配) 匹配成功匹配正则表达式REGEXP的所有行。若REGEXP本身含有斜杠字符(/),则要用转义字 符反斜杠(\)进行转义:即\/,一个空的正则表达式(//),表示重复最近的一个非空的正则表达。空的正则表达式不能和调节器(I或M)一直使用,即 //I和//M是错误的
5、\%REGEXP%(正则表达式匹配) 和/REGEXP/功能一样。只是用字符%作为分隔符,而不是字符/,并且可用其他任意一个单字符作为分隔符。同样,若REGEXP本身含有指定的分隔符,要对它进行转义,
6、/REGEXP/I或\%REGEXP%I(I正则表达式匹配) GNU的扩展功能 调节器I表示不区分大小,其余和上面第4、5项一样  
7、/REGEXP/M或\%REGEXP%M(M正则表达式匹配) GNU的扩展功能 调节器M使正则表达式REGEXP中的元字符^和$除了它们原含义的匹配功能外,元字符^和$还分别匹配:换行符后的空字符串和换行符前的空字符串。M是代表多行(Multi-line)的含义。而\` 和 \‘总是分别匹配缓冲的开始和结束
8、NONE(全匹配) 没有指定地址时,即匹配输入文件中的所有行。
9、FIRST,END(区间匹配) 匹配行号从起始行(含)到终止行(含)之间的所有行,若终止行数值小于等于起始行数值,则只匹配行号等于 起始行的一行文本,若终止行是一个正则表达式(REGEXP),则从起始行的下一行开始匹配这个正则表达式,一旦匹配(含匹配行)就结束,或直到输入数据 流结束(若有选项-i或-s时就是输入文件尾)
10、0,/REGEXP/(排除匹配) 这是唯一可以指定行号为0的形式,表示从文件第一行就开始尝试匹配指定的正则表达式,一旦匹配就结束
11、ADDR1,+N(连续匹配) 匹配ADDR1行及其后连续的N行
12、ADDR1,~ N(跳跃匹配) 匹配ADDR1行及其后行号是N的倍数的所有行。
13、!(反向匹配) 可以在以上12种地址形式后加一个惊叹号字符(!),表示反向匹配指定的地址,即匹配那些不在指定地址范围内的行
注意:
 1、不允许指定地址的命令有(即所有行都会执行):
 ①、:label;②、#;③、}
 2、最多能指定一个地址的命令有:
 ①、=;②、a\;③、i\;④、q ;⑤、Q;⑥、r;⑦、R
 3、可指定多个地址的命令有:
 ①、{;②、b;③、t;④、T;⑤、c\;⑥、d;⑦、D;⑧、h;⑨、H;⑩、g;⑾、G;⑿、l;⒀、n;⒁、N;⒂、p;⒃、P;⒄、s;⒅、w;⒆、W;⒇、y

 

元字符表
 元字符        含义说明
 *     将* 前面的那一个正则表达式匹配的结果重复任意次(含0次)。前面的正则表达式可能是一个普通字符,或一个转义的元字符,或一个元字符句点( . ),或一个方括号表达式,或一个\(regexp\)。为了更好的可移植性,在要匹配星号( * )本身时,要用转义字符。
 \+     与星号( * )相同,只是至少重复1次。是 GNU的扩展功能。
 \?     与星号( * )相同,只是最多重复1次。是 GNU的扩展功能。
 \{i\}    与星号( * )相同,只是重复指定的i次。i的值必须介于 0至 RE_DUP_MAX (含)之间。RE_ DUP_ MAX是 POSIX定义的符号型常数,可通过getconf命令取得,最小值为255。
 \{i,j\}    与星号( * )相同,只是重复i至j次。
 \{i, \}    与星号( * )相同,只是至少重复i次。
 \(regexp\)   将regexp看作一个整体,用于:1、上面第1到第 6项的重复匹配中,如\(abc\)+ 匹配至少有一个整体abc的字符串。2、定义后向引用的子表达式。
 .     匹配任意单个字符。
 ^     匹配模版空间(PATTERN SPACE) 开始处的 NULL字符串,即任何出现在字符^后面的东西,必须是位于模版空间的开始处才能成功匹配。只有作为正则表达式的第一个字符或子表达式的第一个字符(在\(  或  \| 之后),字符^才有此作用,否则只是普通字符。为了更好的可移植性,不要在子表达式中使用此功能。
 $     同字符^类似,只是匹配的是模版空间结束处,只有作为正则表达式的最后一个字符或子表达式的最后一个字符(在\)  或  \| 之前),才有此作用,否则只是普通字符。为了更好的可移植性,不要在子表达式中使用此功能。
 [list]、[ ^list] 匹配方括号中的字符列表中的任意一个。1、第一个字符为脱字符( ^),则表示否定匹配,即匹配除字符列表中列出的那些字符以外的所有字符。 2、方括号中的连字符( - ):不是第一或最后一个字符时,只表示连续字符的范围(注意:范围会因 locale而有所不同,因此不具可移植性),否则作为普通字符进行匹配。3、要匹配右方括号( ] )必须将它作为字符列表中的第一个字符。4、所有其他的元字符都看作为普通字符进行匹配。5、方括号表达式里可以含有POSIX定义的类字符 ([..][==][::])。6、当系统没有完全遵守 POSIX标准时(即没设置 export POSIXLY_CORRECT=true ),能识别方括号中含有的,且在 GNU对转义字符功能扩展中定义的转义功能,如\n表示换行符;否则不能识别,即\n表示两字符\和 n 。
 regexp1\ | regexp2  用在相邻的正则表达式之间,表示匹配这些正则表达式中任一个都可以。匹配是从左向右开始的,一旦匹配就不在尝试下一个正则表达式。是 GNU的扩展功能。
 regexp1regexp2  匹配regexp1和regexp2的连接结果。
 \digit    匹配正则表达式前半部分定义的后向引用的第 digit个子表达式。digit为1至9的数字, 1为从左开始。
 \n     匹配换行符。
 \meta    将元字符meta转换成普通字符,以便匹配该字符本身,有$ 、  * 、  . 、[ 、  \  和  ^。
 
sed的3个编程命令
1、:Label
 不允许有地址。无空格。
 在分支命令的位置前指定标签Label,是没有操作指令的。
2、b [Label]
 无条件地跳到分支Label的位置。省略Label时,立即开始(无选项-n时,会先显示模版空间)下一个sed处理循环。
3、t [Label]
 仅当分支条件符合时,或自从读取上一输入行后有过一次成功替换时,就跳到分支Label的位置。省略Label时,立即开始(无选项-n时,会先显示模版空间)下一个sed处理循环。

 

GNU sed的9个扩展命令
1、e [Command]
 允许将来自Shell命令的输出通过管道输入到模版空间。
 ①、没有指定Command时,在模版空间中被发现的Shell命令会被执行,并用执行结果取代模版空间中的数据,会自动去掉执行结果尾部的换行符。这类似于s命令的标志选项e功能。
 ②、指定Command时,就执行Command,并像r命令那样,将执行结果送到输出流;这个命令可以跨度多行,除了最后一行,每行要以一个反斜杠(\)结尾。
 上面两种情况中,当被执行的命令包含NUL字符时,结果是没有定义的。
2、F
 显示当前输入文件的文件名,会自动进行换行。
3、L n
 在将来的版本中会删除此命令。
4、Q [Exit-code]
 只接受单一匹配的sed地址。表示退出sed,不再处理任何命令或输入,一定不前会显示当前模版空间中的数据。若指定了退出代码,则返回它。
5、R Filename
 在当前循环(即处理当前模版空间的过程)结束时,或当前循环没处理完,在读取下一输入行前时,将文件Filename的内容排成一行、读取并插入到输出流。注意,若文件Filename不能读取,就当作是一个空文件,是没有任何错误提示的。
 在GNU sed中,文件可以是/dev/stdin,表示读取标准输入中一行内容。
6、T Label
 仅当分支条件符合时,或自从读取上一输入行后没有过一次成功替换时,就跳到分支Label的位置。省略Label时,立即开始(无选项-n时,会先显示模版空间)下一个sed处理循环。
7、v [Version]
 用来验证是否支持GNU sed的扩展功能,若不支持将使sed失败。同时,还可指定脚本要求的sed版本Version,如4.0.5,默认是4.0。
 这命令会启用所有GNU的扩展功能,即使用环境变量POSIXLY_CORRECT取消也不行。
8、W Filename
 将从模版空间的开始直到第一个换行符的数据写入文件Filename,其他的同命令w一样。
9、z
 清空模版空间的内容,基本等同于命令s/.*//的作用,但比后者更有效、更可靠。
 POSIX规定:元字符句点(.)是不能匹配不合法的多字节序列。所以,在大多数多字节地区(包括UTF-8地区),不能在脚本中实现可移植的清空sed缓冲区的方法。
 
其中“//D”是什么意思??"//"是简写,//代表使用上一次的正则

 

模式空间就是读入行所在的缓存,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的行
:lable
 在脚本中标记一行,用于实现由b或t的控制转移。Label最多可以包含7个字符
=
 =[address]=  将所寻址的行编写到标准输出,打印模式匹配的行号,使用格式 /pattern/=,整个文件都打印出来,并且匹配行打印了行号。如果只关心实际行号,使用 -e选项
a
 [address]a  text  在与address匹配的每行后面追加text。如果text多于一行,必须用反斜杠将这些行前面的换行符“隐藏”起来。Text将被没有用这种方法隐藏 的第一个换行符结束。Text在模式空间中是不可用的并且后续的命令不能应用于它。当编辑命令的列表用完时,这个命令的结果将被输送到标准输出,而不管在 模式空间中的当前行发生了什么
b
 [address1[,address2]]b[label] 无条件地将控制转移到脚本的其他位置的:label处。也就是说,label后面的命令是应用于当前行的下一个命令。如果没有指定label, 控制将一直到达脚本的末端,因此不再有命令作用于当前行
c
 [address1[,address2]]c  text 用text替代(改变)由地址选定的行。当指定的是一个行范围时,将所有的这些行作为一个组由text的一个副本来替代。每个text行后面的换行符必须用反斜杠将其转义,但最后一行除外。实际上,模式空间的内容被删除,因此后续的命令不能应用于它(或应用于text)
d
 [address1[,address2]]d  从模式空间中删除行。因此行没有传递到标准输出。一个新的输入行被读取,并用脚本的第一个命令来编辑
D
 [address1[,address2]]D  删除由命令N创建的多行模式空间中的一部分(直到嵌入的换行符),并且用脚本的第一条命令恢复编辑。如果这个命令使模式空间为空,那么将读取一个新的输入行,和执行了d命令一样
g
 [address1[,address2]]g  将保持空间(参见h或H命令)中的内容复制到模式空间中,并将当前的内容清除
G
 [address1[,address2]]G  将换行符后的保持空间(参见h或H命令)内容追加到模式空间。如果保持空间为空,则将换行符添加到模式空间
h
 [address1[,address2]]h  将模式空间的内容复制到保存空间,即一个特殊的临时缓冲区。保存空间的当前内容被清除
H
 [address1],address2]]H  将换行符和模式空间的内容追加到保持空间中,即使保持空间为空,这个命令也追加换行符
i
 [address1]i text 将text插入到每个和address匹配的行的前面
l
 [address1[,address2]]l  列出模式空间的内容,将不可打印的字符表示为ASCII码。长的行被折行
n
 [address1[,address2]]n 读取下一个输入行到模式空间。当前行被送到标准输出。新行成为当前行并递增行计数器。将控制转到n后面的命令,而不是恢复到脚本的顶部
N
 [address1[,address2]]N 将下一个输入行追加到模式空间的内容之后;新添加的行与模式空间的当前内容用换行符分隔(这个命令用于实现跨两行的模式匹配。利用n来匹配嵌入的换行符,则可以实现多行匹配模式)
p
 [address1[,address2]]p  打印所寻址的行。注意这将导致输出的重复,除非默认的输出用”#n”或”-n”命令行选项限制。常用于改变流控制(d,n,b)的命令之前并可能阻止当前行被输出
P
 [address1[,address2]]P  打印由命令N创建的多行模式空间的第一部分(直接嵌入的换行符)。如果没有将N应用于某一行则和p相同
q
 [address]q  当遇到address时退出。寻址的行首先被写到输出(如果没有限制默认输出),包括前面的a或r命令为它追加的文本
r
 [address]r file 读取file的内容并追加到模式空间内容的后面。必须在r和文件名file之间保留一个空格
s
 [address1[,address2]]s/pattern/replacement/[flags]  用replacement代替每个寻址的pattern。如果使用了模式地址,那么模式//表示最后指定的模式地址。可以指定下面的标志:
  n 替代每个寻址的行的第n个/pattern/。N是1到512之间的任意数字,并且默认值为1
  g 替代每个寻址的行的所有/pattern/,而不只是第一个
  p 如果替换成功则打印这一行。如果成功进行了多个替换,将打印这个行的多个副本
  w file 如果发生一次替换则将这行写入file。最多可以打开10个不同的file
  replacement是一个字符串,用来替换与正则表达式匹配的内容.在replacement部分,只有下列字符有特殊含义:
   &  用正则表达式匹配的内容进行替换
   n 匹配第n个子串(n是一个数字),这个子串以前在pattern中用"("和")"指定
   当在替换部分包含"与"符号(&),反斜杠()和替换命令的定界符时可用转义它们.另外,它用于转义换行符并创建多行replacement字符串

 

  数字标志 s/pattern/replacememt/flag 如果flag是数字, 那么指定对一行上某个位置的匹配.如果没有数字标志,则替换命令只替换第一个匹配串,因此"1"可以被看作是默认的数字标志

 

  替换元字符是反斜杠()、与符号(&)和n:
  反斜杠一般用于转义其他的元字符,但是它在替换字符串中也用于包含换行符。
  例如对于如下的行:column1(制表符)column2(制表符)column3(制表符)column4 使用如下替换语句:s/制表符//2 注意,在反斜杠的后面不允许有空格。这个脚本产生下面的结果:
   column1(制表符)column2
   column3(制表符)column4
  "与"符号(&)作为元字符表示模式匹配的范围,不是被匹配的行.例如下面的命令:s/UNIX/s-2&s0/g 可以将输入行:on the UNIX Operating System 替换成:on the s-2UNIXs0 Operating System。当正则表达式匹配单词的变化时,"与"符号特别有用.它允许指定一个可变的替换字符串.诸如"See Section 1.4"或"See Section 12.9"的引用都应该出现在圆括号中,如"(See Section 12.9)".正则表达式可以匹配数字的不同组合,所以在替换字符串中可以使用"&"并括起所匹配的内容:s/See Section [1-9][0-9]*.[1-9][0-9]*/(&)/ 这里"与"符号用于在替换字符串中引用整个匹配内容
  n元字符用于选择被匹配的字符串的任意独立部分,并且在替换字符串中回调它.在sed中转义的圆括号括住正则表达式的任意部分并且保存以备回调.一行最多允许保存9次.例如,当节号出现在交叉引用中时要表示为用粗体:s/(See Section )([1-9][0-9]*.[1-9][0-9]*)/1fB2fp/
t
 [address1[,address2]]t[label] 测试在寻址的行范围内是否成功执行了替换,如果是,则转移到有label标志的行(参见b和:)。如果没有给出label,控制将转移到脚本的底部
w
 [address1[,address2]]w file  将模式空间的内容追加到file。这个动作是在遇到命令时发生而不是在输出模式空间内容时发生。必须在w和这个文件名之间保留一个空格。在脚 本中可以打开的最大文件数是10。如果文件不存在,这个命令将创建一个文件。如果文件存在,则每次执行脚本时将改写其内容,多重写入命令直接将输出写入到 同一个文件并追加到这个文件的末端
x
 [address1[,address2]]x  交换模式空间和保持空间的内容
y
 [address1[,address2]]y/abc/xyz/  按位置将字符串abc中的字符替换成字符串xyz中相应字符
 
在使用sed时,替换变量出现特殊字符,此时变量需要用"${var}"括起来,从shell向sed传值,要从命令行中向sed传值,值得注意的是用双引号,否则功能不执行.
"‘$var‘"
 这种写法大家无需改变用‘括起awk程序的习惯.如:var="test" awk ‘BEGIN{print "‘$var‘"}‘
 这种写法是双括号变为单括号的常量,传递给了awk.如果var中含空格,为了shell不把空格作为分格符,应如下使用:
 var="this is a test"
 awk ‘BEGIN{print "‘"$var"‘"}‘

 

‘"$var"‘
 如果变量含空格,则变为‘""$var""‘较为可靠.

 

把括起awk程序的‘‘变为"",使用"$var"
 如:
 $var="this is a test"
 awk ‘BEGIN{print "$var"}"
 因为在""里$是特殊字符,而在‘‘里$是普通字符.

 

export 变量,使用ENVIRON["var"]形式
 如:
 $var="this is a test";export $var
 awk ‘BEGIN{print ENVIRON["var"]}‘

 

也可以使用-v选项
 如:
 $var="this is a test"
 awk -vnvar="$var" ‘{print nvar}‘
 这样便把系统变量定义成了awk变量.

 

在awk中给系统变量附值
eval $(awk ‘BEGIN{print "a=ggg b=3"}‘)
eval $(grep -v ‘#‘ "$CONFFILE" | awk ‘BEGIN{FS="|"} NR=="‘$var_list‘"{printf("HOST=\"%s\" MAX=\"%s\" EMAILLIST=\"%s\" PHONE=\"%s\"\n",$1,$2,$3,$4)}‘)

 

倒序文件 sed -e ‘1!G;h;$!d‘ a.txt > b.txt
 把保留空间(临时缓冲区)的内容附接到当前行的模式空间,删除当前行模式空间,如此往复,直到最后一行,到最后一行的时候不删除当前模式空间,最后输出模式空间。上述sed命令‘1!G;h;$!d‘,用分号隔开三个子命令G, h, d,应用于每一行的分析,G表示把缓冲区内容附接到当前模式空间中,h表示将模式空间的内容保存到缓冲区中,d表示删除模式空间。
 
去掉<xx>abcdefg</xxx>内容两边的括号,如果内容之间有换行,又该如何办?
 *没有换行的情况:
  echo "<xx>abcdefg</xxx>" | sed ‘s/\(<.*>\)\(.*\)\(<.*>\)/\2/‘
  echo "<xx>abcdefg</xxx>" | sed ‘s/<[^>]*>//g‘ 
 *内容中有换行的情况
 #cat test.sed
 #!/bin/sed -f
 :a
 /<[^>]*$/{
  N
  ba
 }
 s/<[^>]*>//g

 

删除配置文件中#号注释的行
 sed ‘s#\#.*##‘ file.conf > file.new.conf
 sed -i ‘s#\#.*##‘ file.conf
 grep -v "#" file.conf

 

删除配置文件中//号注释的行
 sed ‘s#//.*##‘ file.conf > file.new.conf
 grep -v  ‘^//‘ file.conf

 

单引号内所有元字符都失去特殊含义(包括\),双引号内除了变量域($)和命令域(‘)以外的元字符都失去特殊含义,一般使用双引号引用.花括号{}被用来区分变量名和周围的文本:echo ${file} and $file1 寻找变量file,file1.‘‘命令替代的格式:反引号来环绕一个命令像‘cmd‘,和$(cmmand)是等价的:echo ${ls} = echo ‘ls‘ 执行此选项中的命令

 

对ip地址进行替换和修改
 #在sed中使用变量
 aa=0
 bb=77
 sed "1,2{s/\([0-9]\{1,3\}\.[0-9]\{1,3\}\.\)$aa\(\.[0-9]\{1,3\}\)/\1$bb\2/}" file
 其中的中间()号中的是对IP地址的匹配。注意其IP地址的正则表达的匹配方式。而前面的1,2表示需要处理的起止行数

 

删除文件中的后两行
 sed -i "$d" file | sed -i "$d" file 或 sed ‘N;$d;P;D‘

 

匹配一行中的或关系的多个字符串
 awk ‘/string1/||/string2/ { print $0 }‘ file 或 sed -n "/string1\|string2/p" file 

 

取特定数目倍数的行
 nl filename | awk ‘(NR-3)%3==0‘ 取filename中3,2×3,3×3,3×4等行,当然也可以把逻辑变换以下,取任意于行数相关的行。

 

选出以数字开头的行,该行的数字要大于10位
 sed -n ‘/^[0-9]\{10,\}/p‘ ff

 

把/usr/local:替换成/usr:
 sed -e ‘s/\(\/usr\).*/\1:/g‘ file
 sed -e ‘s/\/usr/local:/\/usr:/g‘ file
 sed -e ‘s:/usr/local:/usr:g‘ file
 awk -F‘/‘ ‘{print "/"$2":"}‘

 

有文件d7如下,请把第三行的7全部变成8
 20080602/1/6/2
 20080602/2/7/3
 20080602/3/7/2
 20080602/4/6/3
 sed -e ‘s/\(.*\/.*\/\)7\(\/.*\)/\18\2/‘ file
 awk -F‘/‘ ‘{if($3==7) {$3=8} print $1"/"$2"/"$3"/"$4}‘ file
 awk -F "/" ‘{OFS="/"}{if($3==7) $3=8; print $0}‘ file

 

取一行中的特定段的字符的方法总结
 1) sed
 2) awk
 3) cut
 4) grep

 

 *)删除文件中的前10000行
 1) sed ‘1,10000d‘ file
 2) awk ‘NR>10000‘ file
 *)删除含有特定字符串1到特定字符串2的行
 1) sed ‘/str1/,/str2/d‘ file

 

把文件中的所有行末尾的\n都去掉;把文件组成一行
 sed ‘{:a;N;s/\n/ /;ba}‘ filename
 这是一个循环,用N来读取下一行并追加到模式空间中;用标签:a和跳转b来循环这个过程

 

每隔两行进行合并
 sed ‘{N;s/\n/ /}‘ filename

 

把文中的单词(以,号隔开)的格式化成,每行一个(用\n替换掉,即可)
 sed ‘s/,/\n/g‘ filename

 

替换一列
 11 22 33
 11 22 33
 替换第一列为55
 sed ‘s/^11/55/‘ file
 替换第2列为66
 sed ‘s/\(.*\) .* \(.*\)/\1 66 \2/‘ file

 

删除空白(由tab和空格或只有\n的行组成)行
 sed ‘/^[ \t\n]*$/d‘ file
 sed ‘/^[[:space:]]*$/d‘

 

替换每行的第2个字符到第6个字符为*号
 sed ‘s/\(^.\).\{5\}\(.*\)/\1*****\2/‘
 sed ‘{s/.3;s/.5;s/./‘

 

将每一行拖尾的“空白字符”(空格,制表符)删除
 sed ‘s/[ \t]*$//‘

 

将每一行中的前导和拖尾的空白字符删除
 sed ‘s/^[ \t]*//;s/[ \t]*$//‘

 

在每一行开头处插入5个空格(使全文向右移动5个字符的位置)
 sed ‘s/^/     /‘

 

以79个字符为宽度,将所有文本右对齐
 sed -e :a -e ‘s/^.\{1,78\}$/ &/;ta‘  #78个字符外加最后的一个空格

 

以79个字符为宽度,使所有文本居中。在方法1中,为了让文本居中每一行的前头和后头都填充了空格。 在方法2中,在居中文本的过程中只在文本的前面填充空格,并且最终这些空格将有一半会被删除。此外每一行的后头并未填充空格
 sed  -e :a -e ‘s/^.\{1,77\}$/ & /;ta‘
 sed  -e :a -e ‘s/^.\{1,77\}$/ &/;ta‘ -e ‘s/\( *\)\1/\1/‘

 

在每一行中查找字串“foo”,并将找到的“foo”替换为“bar”
 sed ‘s/foo/bar/‘
 sed ‘s/foo/bar/4‘
 sed ‘s/foo/bar/g‘
 sed ‘s/\(.*\)foo\(.*foo\)/\1bar\2/‘
 sed ‘s/\(.*\)foo/\1bar/‘

 

只在行中出现字串“baz”的情况下将“foo”替换成“bar”
 sed ‘/baz/s/foo/bar/g‘

 

将“foo”替换成“bar”,并且只在行中未出现字串“baz”的情况下替换
 sed ‘/baz/!s/foo/bar/g‘

 

不管是“scarlet”“ruby”还是“puce”,一律换成“red”
 sed ‘s/scarlet/red/g;s/ruby/red/g;s/puce/red/g‘ #对多数的sed都有效
 gsed ‘s/scarlet\|ruby\|puce/red/g‘    #只对GNU sed有效

 

倒置所有行,第一行成为最后一行,依次类推(模拟“tac”)(由于某些原因,使用下面命令时HHsed v1.5会将文件中的空行删除)
 sed ‘1!G;h;$!d‘
 sed -n ‘1!G;h;$p‘

 

将行中的字符逆序排列,第一个字成为最后一字,……(模拟“rev”)
 sed ‘/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//‘

 

将每两行连接成一行(类似“paste”)
 sed ‘$!N;s/\n/ /‘

 

如果当前行以反斜杠“\”结束,则将下一行并到当前行末尾,并去掉原来行尾的反斜杠
 sed -e :a -e ‘/\\$/N; s/\\\n//; ta‘

 

如果当前行以等号开头,将当前行并到上一行末尾,并以单个空格代替原来行头的“=”
 sed -e :a -e ‘$!N;s/\n=/ /;ta‘ -e ‘P;D‘

 

为数字字串增加逗号分隔符号,将“1234567”改为“1,234,567”
 gsed ‘:a;s/\B[0-9]\{3\}\>/,&/;ta‘
 sed -e :a -e ‘s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta‘

 

为带有小数点和负号的数值增加逗号分隔符(GNU sed)
 gsed -r ‘:a;s/(^|[^0-9.])([0-9]+)([0-9]{3})/\1\2,\3/g;ta‘

 

在每5行后增加一空白行 (在第5,10,15,20,等行后增加一空白行)
 gsed ‘0~5G‘
 sed ‘n;n;n;n;G;‘

 

选择性地显示特定行:
 #显示文件中的前10行 (模拟“head”的行为)
 sed 10q
 #显示文件中的第一行 (模拟“head -1”命令)
 sed q
 #显示文件中的最后10行 (模拟“tail”)
 sed -e :a -e ‘$q;N;11,$D;ba‘
 #显示文件中的最后2行(模拟“tail -2”命令)
 sed ‘$!N;$!D‘
 #显示文件中的最后一行(模拟“tail -1”)
 sed ‘$!d‘
 sed -n ‘$p‘

 

显示文件中的倒数第二行
 sed -e ‘$!{h;d;}‘ -e x              #当文件中只有一行时,输入空行
 sed -e ‘1{$q;}‘ -e ‘$!{h;d;}‘ -e x  #当文件中只有一行时,显示该行
 sed -e ‘1{$d;}‘ -e ‘$!{h;d;}‘ -e x  #当文件中只有一行时,不输出

 

只显示匹配正则表达式的行(模拟“grep”)
 sed -n ‘/regexp/p‘
 sed ‘/regexp/!d‘

 

只显示“不”匹配正则表达式的行(模拟“grep -v”)
 sed -n ‘/regexp/!p‘
 sed ‘/regexp/d‘

 

查找“regexp”并将匹配行的上一行显示出来,但并不显示匹配行
 sed -n ‘/regexp/{g;1!p;};h‘

 

查找“regexp”并将匹配行的下一行显示出来,但并不显示匹配行
 sed -n ‘/regexp/{n;p;}‘

 

显示包含“regexp”的行及其前后行,并在第一行之前加上“regexp”所在行的行号 (类似“grep -A1 -B1”)
 sed -n -e ‘/regexp/{=;x;1!p;g;$!N;p;D;}‘ -e h

 

显示包含“AAA”、“BBB”或“CCC”的行(任意次序)
 sed ‘/AAA/!d; /BBB/!d; /CCC/!d‘

 

显示包含“AAA”、“BBB”和“CCC”的行(固定次序)
 sed ‘/AAA.*BBB.*CCC/!d‘

 

显示包含“AAA”“BBB”或“CCC”的行 (模拟“egrep”)
 sed -e ‘/AAA/b‘ -e ‘/BBB/b‘ -e ‘/CCC/b‘ -e d #多数sed
 gsed ‘/AAA\|BBB\|CCC/!d‘      #对GNU sed有效

 

显示包含“AAA”的段落 (段落间以空行分隔),HHsed v1.5 必须在“x;”后加入“G;”,接下来的3个脚本都是这样
 sed -e ‘/./{H;$!d;}‘ -e ‘x;/AAA/!d;‘

 

显示包含“AAA”“BBB”和“CCC”三个字串的段落 (任意次序)
 sed -e ‘/./{H;$!d;}‘ -e ‘x;/AAA/!d;/BBB/!d;/CCC/!d‘

 

显示包含“AAA”、“BBB”、“CCC”三者中任一字串的段落 (任意次序)
 sed -e ‘/./{H;$!d;}‘ -e ‘x;/AAA/b‘ -e ‘/BBB/b‘ -e ‘/CCC/b‘ -e d
 gsed ‘/./{H;$!d;};x;/AAA\|BBB\|CCC/b;d‘         #只对GNU sed有效

 

显示包含65个或以上字符的行
 sed -n ‘/^.\{65\}/p‘

 

显示包含65个以下字符的行
 sed -n ‘/^.\{65\}/!p‘
 sed ‘/^.\{65\}/d‘
 
显示部分文本——从包含正则表达式的行开始到最后一行结束
 sed -n ‘/regexp/,$p‘
 
显示部分文本——指定行号范围(从第8至第12行,含8和12行)
 sed -n ‘8,12p‘
 sed ‘8,12!d‘
 
显示第52行
 sed -n ‘52p‘
 sed ‘52!d‘
 sed ‘52q;d‘
 
从第3行开始,每7行显示一次
 gsed -n ‘3~7p‘                   #只对GNU sed有效
 sed -n ‘3,${p;n;n;n;n;n;n;}‘     #其他sed
 
显示两个正则表达式之间的文本(包含)
 sed -n ‘/Iowa/,/Montana/p‘       #区分大小写方式
 
显示通篇文档,除了两个正则表达式之间的内容
 sed ‘/Iowa/,/Montana/d‘
 
删除文件中相邻的重复行(模拟“uniq”),只保留重复行中的第一行,其他行删除
 sed ‘$!N; /^\(.*\)\n\1$/!P; D‘
 
删除文件中的重复行,不管有无相邻,注意hold space所能支持的缓存大小,或者使用GNU sed
 sed -n ‘G; s/\n/&&/; /^\([ -~]*\n\).*\n\1/d; s/\n//; h; P‘
 
删除除重复行外的所有行(模拟“uniq -d”)
 sed ‘$!N; s/^\(.*\)\n\1$/\1/; t; D‘
 
删除文件中开头的10行
 sed ‘1,10d‘
 
删除文件中的最后一行
 sed ‘$d‘
 
删除文件中的最后两行
 sed ‘N;$!P;$!D;$d‘
 
删除文件中的最后10行
 sed -e :a -e ‘$d;N;2,10ba‘ -e ‘P;D‘
 sed -n -e :a -e ‘1,10!{P;N;D;};N;ba‘
 
删除8的倍数行
 gsed ‘0~8d‘                           #只对GNU sed有效
 sed ‘n;n;n;n;n;n;n;d;‘                #其他sed
 
删除匹配式样的行
 sed ‘/pattern/d‘
 
删除文件中的所有空行(与“grep ‘.‘ ”效果相同)
 sed ‘/^$/d‘
 sed ‘/./!d‘
 
只保留多个相邻空行的第一行,并且删除文件顶部和尾部的空行,(模拟“cat -s”)
 sed ‘/./,/^$/!d‘        #删除文件顶部的空行,允许尾部保留一空行
 sed ‘/^$/N;/\n$/D‘      #允许顶部保留一空行,尾部不留空行
 
只保留多个相邻空行的前两行
 sed ‘/^$/N;/\n$/N;//D‘
 
删除文件顶部的所有空行
 sed ‘/./,$!d‘
 
删除文件尾部的所有空行
 sed -e :a -e ‘/^\n*$/{$d;N;ba‘ -e ‘}‘
 sed -e :a -e ‘/^\n*$/N;/\n$/ba‘
 
删除每个段落的最后一行
 sed -n ‘/^$/{p;h;};/./{x;/./p;}‘
 
移除手册页(man page)中的nroff标记。在Unix System V或bash shell下使用‘echo‘命令时可能需要加上 -e 选项
 sed "s/.`echo \\\b`//g"    #外层的双括号是必须的(Unix环境)
 sed ‘s/.^H//g‘             #在bash或tcsh中, 按 Ctrl-V 再按 Ctrl-H
 sed ‘s/.\x08//g‘           #sed 1.5,GNU sed,ssed所使用的十六进制的表示方法
 
提取新闻组或 e-mail 的邮件头
 sed ‘/^$/q‘                #删除第一行空行后的所有内容
 
提取新闻组或 e-mail 的正文部分
 sed ‘1,/^$/d‘              #删除第一行空行之前的所有内容
 
从邮件头提取“Subject”(标题栏字段),并移除开头的“Subject:”字样
 sed ‘/^Subject: */!d; s///;q‘
 
从邮件头获得回复地址
 sed ‘/^Reply-To:/q; /^From:/h; /./d;g;q‘
 
获取邮件地址。在上一个脚本所产生的那一行邮件头的基础上进一步的将非电邮地址的部分剃除
 sed ‘s/ *(.*)//; s/>.*//; s/.*[:<] *//‘
 
在每一行开头加上一个尖括号和空格(引用信息)
 sed ‘s/^/> /‘
 
将每一行开头处的尖括号和空格删除(解除引用)
 sed ‘s/^> //‘
 
移除大部分的HTML标签(包括跨行标签)
 sed -e :a -e ‘s/<[^>]*>//g;/</N;//ba‘
 
将分成多卷的uuencode文件解码。移除文件头信息,只保留uuencode编码部分,文件必须以特定顺序传给sed,下面第一种版本的脚本可以直接在命令行下输入,第二种版本则可以放入一个带执行权限的shell脚本中
 sed ‘/^end/,/^begin/d‘ file1 file2 ... fileX | uudecode   #vers. 1
 sed ‘/^end/,/^begin/d‘ "$@" | uudecode                    #vers. 2
 
将文件中的段落以字母顺序排序。段落间以(一行或多行)空行分隔。GNU sed使用字元“\v”来表示垂直制表符,这里用它来作为换行符的占位符——当然你也可以用其他未在文件中使用的字符来代替它。
 sed ‘/./{H;d;};x;s/\n/={NL}=/g‘ file | sort | sed ‘1s/={NL}=//;s/={NL}=/\n/g‘
 gsed ‘/./{H;d};x;y/\n/\v/‘ file | sort | sed ‘1s/\v//;y/\v/\n/‘
 
分别压缩每个.TXT文件,压缩后删除原来的文件并将压缩后的.ZIP文件命名为与原来相同的名字(只是扩展名不同)(DOS环境:“dir /b”#显示不带路径的文件名)
 echo @echo off >zipup.bat
 dir /b *.txt | sed "s/^\(.*\)\.TXT/pkzip -mo \1 \1.TXT/" >>zipup.bat
 dir /b *.txt | sed "s/^\(.*\)\.TXT/pkzip -mo \1 \1.TXT/" >>zipup.bat

 

 ‘s/\.$//g’                  删除以句点结尾行
 ‘-e /abcd/d’                删除包含abcd的行
 ‘s/[][][]*/[]/g’            删除一个以上空格,用一个空格代替
 ‘s/^[][]*//g’               删除行首空格
 ‘s/\.[][]*/[]/g’            删除句点后跟两个或更多空格,代之以一个空格
 ‘/^$/d’                     删除空行
 ‘s/^.//g’                   删除第一个字符
 ‘s/COL\(...\)//g’           删除紧跟COL的后三个字母
 ‘s/^\///g’                  从路径中删除第一个\
 ‘s/[]/[]//g’                删除所有空格并用tab键替代
 ‘S/^[]//g’                  删除行首所有tab键
 ‘s/[]*//g’                  删除所有tab键
 
sed常用操作
删除配置文件中#号注释行
 sed   ‘ s#\#. :e## ‘   _       .conf  >   ~       .new.conf

 

删除配置文件中//号注释行
 sed ‘s#//.*##‘ file.conf > file.new.conf
 
删除无内容空行
 sed ‘/^$/d‘ file.conf > file.new.conf
 
删除由空格和Tab而成的空行
 sed ‘/^[[:space:]]*$/d‘ file.conf > file.new.conf
 
sed—i可以直接写入不用>
 grep对应的用法
 删除配置文件中#号注释行
    sed ‘s#\#.*##‘ file.conf > file.new.conf
    sed -i ‘s#\#.*##‘ file.conf
    grep -v "#" file.conf
 
删除配置文件中//号注释行
    sed ‘s#//.*##‘ file.conf > file.new.conf
    grep -v  ‘^//‘ file.conf
 
删除无内容空行
 sed ‘/^$/d‘ file.conf > file.new.conf
    grep -v ‘^$‘  file.conf
 
删除由空格和Tab而成的
 sed ‘/^[[ : space: ] ]*$/d ‘ file.conf > file.new.conf
 grep [ : space : ] file.conf

 

利用sed取行/替换
单引号、双引号、括号、花括号及反引号
 单引号内所有元字符都失去特殊含义(包括\)双引号内除了变量域($)和命令域(‘)以外的元字符都失去特殊含义,所以一般使用双引号引用
 花括号{}被用来区分变量名和周围的文本:echo ${f.le)and $filel寻找变量file,filel
 ‘‘命令替代的格式:反引号来环绕一个命令象‘cmd‘,它和$(command)是等价的echo
 ${ls)=echo \ls‘,‘执行此选项中的命令‘
取行
 sed—n“3”p file取第3行
 sed—n“1,3“p file取第1到3行
 sed—n“1,$“p file取第1到最后一行
 sed—n“1,$num”p file取第1至0 num行
 sed—n“\$p“file取最后1行
 sed—e‘1 1Gj hj$!d‘file倒过来显示
sed附加/替换
 sed “/xmdh/a\daoyou“ file 把含有xmdh的行的结尾附加daoyou(有换行)
 sed ‘s/$/  daoyou/’file  把每行的结尾附加daoyou(在同一行)
 sed ’/test/s/$/ daoyou/‘ file把包含test行的结尾附加daoyou(在同一行)
 sed ‘10s/$/ daoyou/’file 把第10行的结尾附加daoyou(在同一行)
 sed "s/xmdh/daoyou/g" file 把xmdh替换成daoyou
 sed "s/xmdh/daoyou/;G" file 把xmdh替换成daoyou并增加一个换行
 cat userlog | sed —n ’/xmdh/w test.txt’ 查看含有xmdh并写入test .txt中
搜索
 vi file后: /\<daoyou\>/
显示行号
 awk ‘/dhshunde/{print NR,$O}‘ userlog 或 grep -n dhshunde userlog显示含有dhshunde的行号及内容
 cat userlog lsed—n‘/erptest/=’  显示含有erptest的行号
 cat userlog lsed—n’/xmdh/p‘ | sed—n’$p’ 显示包含xmdh的最后一行
awk中使用变量
 /bin/cat /etc/ppp/chap-secretslgrep $5lawk ‘{print
 logoutt ime " \t " , -‘ u sername : -‘ $1 -‘ \t -‘ , " logout " -‘ \t -‘ , -‘ data : -‘ data size}
 logouttime=" - /bin/date- "datasize= "$size"
 >>$pptplogdirectory/userlog (注:   size前面已经有定义)
find的用法
注:find命令将所有匹配到的文件一起传递给exec执行,而xargs命令每次只获取一部分文件而不是全部所以exec有长度限制,文件不能太多,否则会产生溢出错误,而xargs别没有
 find.-mtime -1 -print   跟现在小于1天修改的文件
 find.-perm 755 -print   显示具有755属性的文件
 find.-size +1000000c -print 查找大于1M的文件
 find.-type f -exec ls —l {} \;查找文件并列表显示(注:{}与\之间有空格,最后有;)
 find.-type f -exec rm {} \; 查找文件并删除
 find.-type f -print | xargs ls -l 查看文件并列表显示
 find / \(-perm -4000 -o -perm -2000\)-type f- print查找SUID和SGID文件
 
向登录终端用户发送消息
 echo "hello i am jiangdaoyou" |tee /dev/pts/2 (tty可以查看自己的终端号),等同于:write root pts/2然后输入:hello i am jiangdaoyou 然后Ctrl+D结束
 
awk之BEGIN和END
 即在文件头增加列名:
 cat userlog lawk ‘BEGIN{print "Time
 username\n----    一“)j{print$4J$7)
 Time    username
 15:19: 28  username:xmdh
 15: 20: 00  username: xmdh
 即在文件头增加列名:
 cat userlog lawk ‘BEGIN{print "Time
 username\n----    一“);{print$4,$7)‘
 Time username
 
截取/转化字符
 echo  "200604211031" | cut -c9-12 得到 1031
 cat test.ok |tr ‘arp‘ ‘rpm‘ 把 arp转为 rpm
 
求平均值
 vmstat 1 4 |awk ‘{print  $4}‘ |grep -o ‘[0-9]*‘ |sed ‘s/,//g‘ |awk
 ‘{total=total+$l; if(NR%4==0)  {print  total/4}} ‘ 成如下方法:
 vmstat 1 4lawk ‘NR>2{sum+=$4}END{print sum/4}‘
 
循环
 ls | for file in *;do echo "rpm -ivh" $file;done
 ls | for file in $(ls *.rpm);do echo "rpm -ivh" $file;done

 

在每一行后面增加一空行
 sed G

 

将原来的所有空行删除并在每一行后面增加一空行。这样在输出的文本中每一行后面将有且只有一空行。
 sed ‘/^$/d;G‘

 

在每一行后面增加两行空行
 sed ‘G;G‘

 

将第一个脚本所产生的所有空行删除(即删除所有偶数行)
 sed ‘n;d‘

 

在匹配式样“regex”的行之前插入一空行
 sed ‘/regex/{x;p;x;}‘

 

在匹配式样“regex”的行之后插入一空行
 sed ‘/regex/G‘

 

在匹配式样“regex”的行之前和之后各插入一空行
 sed ‘/regex/{x;p;x;G;}‘

 

为文件中的每一行进行编号(简单的左对齐方式)。这里使用了“制表符”(tab,见本文末尾关于‘\t‘的用法的描述)而不是空格来对齐边缘。
 sed = filename | sed ‘N;s/\n/\t/‘

 

对文件中的所有行编号(行号在左,文字右端对齐)。
 sed = filename | sed ‘N; s/^/     /; s/ *\(.\{6,\}\)\n/\1  /‘

 

对文件中的所有行编号,但只显示非空白行的行号。
 sed ‘/./=‘ filename | sed ‘/./N; s/\n/ /‘

 

计算行数 (模拟 "wc -l")
 sed -n ‘$=‘

 

Unix环境:转换DOS的新行符(CR/LF)为Unix格式。
 sed ‘s/.$//‘                     # 假设所有行以CR/LF结束
 sed ‘s/^M$//‘                    # 在bash/tcsh中,将按Ctrl-M改为按Ctrl-V
 sed ‘s/\x0D$//‘                  # ssed、gsed 3.02.80,及更高版本

 

Unix环境:转换Unix的新行符(LF)为DOS格式。
 sed "s/$/`echo -e \\\r`/"        # 在ksh下所使用的命令
 sed ‘s/$‘"/`echo \\\r`/"         # 在bash下所使用的命令
 sed "s/$/`echo \\\r`/"           # 在zsh下所使用的命令
 sed ‘s/$/\r/‘                    # gsed 3.02.80 及更高版本

 

DOS环境:转换Unix新行符(LF)为DOS格式。
 sed "s/$//"                      # 方法 1
 sed -n p                         # 方法 2

 

DOS环境:转换DOS新行符(CR/LF)为Unix格式。
下面的脚本只对UnxUtils sed 4.0.7 及更高版本有效。要识别UnxUtils版本的sed可以通过其特有的“--text”选项。你可以使用帮助选项(“--help”)看其中有无一个 “--text”项以此来判断所使用的是否是UnxUtils版本。其它DOS版本的的sed则无法进行这一转换。但可以用“tr”来实现这一转换。
 sed "s/\r//" infile >outfile     # UnxUtils sed v4.0.7 或更高版本
 tr -d \r <infile >outfile        # GNU tr 1.22 或更高版本

 

将每一行前导的“空白字符”(空格,制表符)删除
 使之左对齐
 sed ‘s/^[ \t]*//‘                # 见本文末尾关于‘\t‘用法的描述

 

 将每一行拖尾的“空白字符”(空格,制表符)删除
 sed ‘s/[ \t]*$//‘                # 见本文末尾关于‘\t‘用法的描述

 

将每一行中的前导和拖尾的空白字符删除
 sed ‘s/^[ \t]*//;s/[ \t]*$//‘

 

在每一行开头处插入5个空格(使全文向右移动5个字符的位置)
 sed ‘s/^/     /‘

 

以79个字符为宽度,将所有文本右对齐
 sed -e :a -e ‘s/^.\{1,78\}$/ &/;ta‘  # 78个字符外加最后的一个空格

 

以79个字符为宽度,使所有文本居中。在方法1中,为了让文本居中每一行的前头和后头都填充了空格。 在方法2中,在居中文本的过程中只在文本的前面填充空格,并且最终这些空格将有一半会被删除。此外每一行的后头并未填充空格。
 sed  -e :a -e ‘s/^.\{1,77\}$/ & /;ta‘                     # 方法1
 sed  -e :a -e ‘s/^.\{1,77\}$/ &/;ta‘ -e ‘s/\( *\)\1/\1/‘  # 方法2

 

在每一行中查找字串“foo”,并将找到的“foo”替换为“bar”
 sed ‘s/foo/bar/‘                 # 只替换每一行中的第一个“foo”字串
 sed ‘s/foo/bar/4‘                # 只替换每一行中的第四个“foo”字串
 sed ‘s/foo/bar/g‘                # 将每一行中的所有“foo”都换成“bar”
 sed ‘s/\(.*\)foo\(.*foo\)/\1bar\2/‘ # 替换倒数第二个“foo”
 sed ‘s/\(.*\)foo/\1bar/‘            # 替换最后一个“foo”

 

只在行中出现字串“baz”的情况下将“foo”替换成“bar”
 sed ‘/baz/s/foo/bar/g‘

 

将“foo”替换成“bar”,并且只在行中未出现字串“baz”的情况下替换
 sed ‘/baz/!s/foo/bar/g‘

 

不管是“scarlet”“ruby”还是“puce”,一律换成“red”
 sed ‘s/scarlet/red/g;s/ruby/red/g;s/puce/red/g‘  #对多数的sed都有效
 gsed ‘s/scarlet\|ruby\|puce/red/g‘               # 只对GNU sed有效

 

倒置所有行,第一行成为最后一行,依次类推(模拟“tac”)。由于某些原因,使用下面命令时HHsed v1.5会将文件中的空行删除
 sed ‘1!G;h;$!d‘               # 方法1
 sed -n ‘1!G;h;$p‘             # 方法2

 

将行中的字符逆序排列,第一个字成为最后一字,……(模拟“rev”)
 sed ‘/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//‘

 

将每两行连接成一行(类似“paste”)
 sed ‘$!N;s/\n/ /‘

 

如果当前行以反斜杠“\”结束,则将下一行并到当前行末尾并去掉原来行尾的反斜杠
 sed -e :a -e ‘/\\$/N; s/\\\n//; ta‘

 

如果当前行以等号开头,将当前行并到上一行末尾并以单个空格代替原来行头的“=”
 sed -e :a -e ‘$!N;s/\n=/ /;ta‘ -e ‘P;D‘

 

为数字字串增加逗号分隔符号,将“1234567”改为“1,234,567”
 gsed ‘:a;s/\B[0-9]\{3\}\>/,&/;ta‘                     # GNU sed
 sed -e :a -e ‘s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta‘  # 其他sed

 

为带有小数点和负号的数值增加逗号分隔符(GNU sed)
 gsed -r ‘:a;s/(^|[^0-9.])([0-9]+)([0-9]{3})/\1\2,\3/g;ta‘

 

在每5行后增加一空白行 (在第5,10,15,20,等行后增加一空白行)
 gsed ‘0~5G‘                      # 只对GNU sed有效
 sed ‘n;n;n;n;G;‘                 # 其他sed

 

显示文件中的前10行 (模拟“head”的行为)
 sed 10q

 

显示文件中的第一行 (模拟“head -1”命令)
 sed q

 

显示文件中的最后10行 (模拟“tail”)
 sed -e :a -e ‘$q;N;11,$D;ba‘

 

显示文件中的最后2行(模拟“tail -2”命令)
 sed ‘$!N;$!D‘

 

显示文件中的最后一行(模拟“tail -1”)
 sed ‘$!d‘                        # 方法1
 sed -n ‘$p‘                      # 方法2

 

显示文件中的倒数第二行
 sed -e ‘$!{h;d;}‘ -e x              # 当文件中只有一行时,输入空行
 sed -e ‘1{$q;}‘ -e ‘$!{h;d;}‘ -e x  # 当文件中只有一行时,显示该行
 sed -e ‘1{$d;}‘ -e ‘$!{h;d;}‘ -e x  # 当文件中只有一行时,不输出

 

只显示匹配正则表达式的行(模拟“grep”)
 sed -n ‘/regexp/p‘               # 方法1
 sed ‘/regexp/!d‘                 # 方法2

 

只显示“不”匹配正则表达式的行(模拟“grep -v”)
 sed -n ‘/regexp/!p‘              # 方法1,与前面的命令相对应
 sed ‘/regexp/d‘                  # 方法2,类似的语法

 

查找“regexp”并将匹配行的上一行显示出来,但并不显示匹配行
 sed -n ‘/regexp/{g;1!p;};h‘

 

查找“regexp”并将匹配行的下一行显示出来,但并不显示匹配行
 sed -n ‘/regexp/{n;p;}‘

 

显示包含“regexp”的行及其前后行,并在第一行之前加上“regexp”所在行的行号 (类似“grep -A1 -B1”)
 sed -n -e ‘/regexp/{=;x;1!p;g;$!N;p;D;}‘ -e h

 

显示包含“AAA”、“BBB”或“CCC”的行(任意次序)
 sed ‘/AAA/!d; /BBB/!d; /CCC/!d‘  # 字串的次序不影响结果

 

显示包含“AAA”、“BBB”和“CCC”的行(固定次序)
 sed ‘/AAA.*BBB.*CCC/!d‘

 

显示包含“AAA”“BBB”或“CCC”的行 (模拟“egrep”)
 sed -e ‘/AAA/b‘ -e ‘/BBB/b‘ -e ‘/CCC/b‘ -e d    # 多数sed
 gsed ‘/AAA\|BBB\|CCC/!d‘                        # 对GNU sed有效

 

显示包含“AAA”的段落 (段落间以空行分隔)
 HHsed v1.5 必须在“x;”后加入“G;”,接下来的3个脚本都是这样
 sed -e ‘/./{H;$!d;}‘ -e ‘x;/AAA/!d;‘

 

显示包含“AAA”“BBB”和“CCC”三个字串的段落 (任意次序)
 sed -e ‘/./{H;$!d;}‘ -e ‘x;/AAA/!d;/BBB/!d;/CCC/!d‘

 

显示包含“AAA”、“BBB”、“CCC”三者中任一字串的段落 (任意次序)
 sed -e ‘/./{H;$!d;}‘ -e ‘x;/AAA/b‘ -e ‘/BBB/b‘ -e ‘/CCC/b‘ -e d
 gsed ‘/./{H;$!d;};x;/AAA\|BBB\|CCC/b;d‘         # 只对GNU sed有效

 

显示包含65个或以上字符的行
 sed -n ‘/^.\{65\}/p‘

 

显示包含65个以下字符的行
 sed -n ‘/^.\{65\}/!p‘            # 方法1,与上面的脚本相对应
 sed ‘/^.\{65\}/d‘                # 方法2,更简便一点的方法

 

显示部分文本——从包含正则表达式的行开始到最后一行结束
 sed -n ‘/regexp/,$p‘

 

显示部分文本——指定行号范围(从第8至第12行,含8和12行)
 sed -n ‘8,12p‘                   # 方法1
 sed ‘8,12!d‘                     # 方法2

 

显示第52行
 sed -n ‘52p‘                     # 方法1
 sed ‘52!d‘                       # 方法2
 sed ‘52q;d‘                      # 方法3, 处理大文件时更有效率

 

从第3行开始,每7行显示一次   
 gsed -n ‘3~7p‘                   # 只对GNU sed有效
 sed -n ‘3,${p;n;n;n;n;n;n;}‘     # 其他sed

 

显示两个正则表达式之间的文本(包含)
 sed -n ‘/Iowa/,/Montana/p‘       # 区分大小写方式

 

显示通篇文档,除了两个正则表达式之间的内容
 sed ‘/Iowa/,/Montana/d‘

 

删除文件中相邻的重复行(模拟“uniq”)只保留重复行中的第一行,其他行删除
 sed ‘$!N; /^\(.*\)\n\1$/!P; D‘

 

删除文件中的重复行,不管有无相邻。注意hold space所能支持的缓存大小,或者使用GNU sed。
 sed -n ‘G; s/\n/&&/; /^\([ -~]*\n\).*\n\1/d; s/\n//; h; P‘

 

删除除重复行外的所有行(模拟“uniq -d”)
 sed ‘$!N; s/^\(.*\)\n\1$/\1/; t; D‘

 

删除文件中开头的10行
 sed ‘1,10d‘

 

删除文件中的最后一行
 sed ‘$d‘

 

删除文件中的最后两行
 sed ‘N;$!P;$!D;$d‘

 

删除文件中的最后10行
 sed -e :a -e ‘$d;N;2,10ba‘ -e ‘P;D‘   # 方法1
 sed -n -e :a -e ‘1,10!{P;N;D;};N;ba‘  # 方法2

 

删除8的倍数行
 gsed ‘0~8d‘                           # 只对GNU sed有效
 sed ‘n;n;n;n;n;n;n;d;‘                # 其他sed

 

删除匹配式样的行
 sed ‘/pattern/d‘                      # 删除含pattern的行。当然pattern可以换成任何有效的正则表达式

 

删除文件中的所有空行(与“grep ‘.‘ ”效果相同)
 sed ‘/^$/d‘                           # 方法1
 sed ‘/./!d‘                           # 方法2

 

只保留多个相邻空行的第一行。并且删除文件顶部和尾部的空行。(模拟“cat -s”)
 sed ‘/./,/^$/!d‘        #方法1,删除文件顶部的空行,允许尾部保留一空行
 sed ‘/^$/N;/\n$/D‘      #方法2,允许顶部保留一空行,尾部不留空行

 

只保留多个相邻空行的前两行。
 sed ‘/^$/N;/\n$/N;//D‘

 

删除文件顶部的所有空行
 sed ‘/./,$!d‘

 

删除文件尾部的所有空行
 sed -e :a -e ‘/^\n*$/{$d;N;ba‘ -e ‘}‘  # 对所有sed有效
 sed -e :a -e ‘/^\n*$/N;/\n$/ba‘        # 同上,但只对 gsed 3.02.*有效

 

删除每个段落的最后一行
 sed -n ‘/^$/{p;h;};/./{x;/./p;}‘

 

移除手册页(man page)中的nroff标记。在Unix System V或bash shell下使用‘echo‘命令时可能需要加上 -e 选项。
 sed "s/.`echo \\\b`//g"    # 外层的双括号是必须的(Unix环境)
 sed ‘s/.^H//g‘             # 在bash或tcsh中, 按 Ctrl-V 再按 Ctrl-H
 sed ‘s/.\x08//g‘           # sed 1.5,GNU sed,ssed所使用的十六进制的表示方法

 

提取新闻组或 e-mail 的邮件头
 sed ‘/^$/q‘                # 删除第一行空行后的所有内容

 

提取新闻组或 e-mail 的正文部分
 sed ‘1,/^$/d‘              # 删除第一行空行之前的所有内容

 

从邮件头提取“Subject”(标题栏字段),并移除开头的“Subject:”字样
 sed ‘/^Subject: */!d; s///;q‘

 

从邮件头获得回复地址
 sed ‘/^Reply-To:/q; /^From:/h; /./d;g;q‘

 

获取邮件地址。在上一个脚本所产生的那一行邮件头的基础上进一步的将非电邮地址的部分剃除。(见上一脚本)
 sed ‘s/ *(.*)//; s/>.*//; s/.*[:<] *//‘

 

在每一行开头加上一个尖括号和空格(引用信息)
 sed ‘s/^/> /‘

 

将每一行开头处的尖括号和空格删除(解除引用)
 sed ‘s/^> //‘

 

移除大部分的HTML标签(包括跨行标签)
 sed -e :a -e ‘s/<[^>]*>//g;/</N;//ba‘

 

将分成多卷的uuencode文件解码。移除文件头信息,只保留uuencode编码部分。文件必须以特定顺序传给sed。下面第一种版本的脚本可以直接在命令行下输入;第二种版本则可以放入一个带执行权限的shell脚本中。(由Rahul Dhesi的一个脚本修改而来。)
 sed ‘/^end/,/^begin/d‘ file1 file2 ... fileX | uudecode   # vers. 1
 sed ‘/^end/,/^begin/d‘ "$@" | uudecode                    # vers. 2

 

将文件中的段落以字母顺序排序。段落间以(一行或多行)空行分隔。GNU sed使用字元“\v”来表示垂直制表符,这里用它来作为换行符的占位符——当然你也可以用其他未在文件中使用的字符来代替它。
 sed ‘/./{H;d;};x;s/\n/={NL}=/g‘ file | sort | sed ‘1s/={NL}=//;s/={NL}=/\n/g‘
 gsed ‘/./{H;d};x;y/\n/\v/‘ file | sort | sed ‘1s/\v//;y/\v/\n/‘

 

分别压缩每个.TXT文件,压缩后删除原来的文件并将压缩后的.ZIP文件命名为与原来相同的名字(只是扩展名不同)。(DOS环境:“dir /b”显示不带路径的文件名)。
 echo @echo off >zipup.bat
 dir /b *.txt | sed "s/^\(.*\)\.TXT/pkzip -mo \1 \1.TXT/" >>zipup.bat

 

使用SED:Sed接受一个或多个编辑命令,并且每读入一行后就依次应用这些命令。当读入第一行输入后,sed对其应用所有的命令,然后将结果输出。接着 再读入第二行输入,对其应用所有的命令……并重复这个过程。上一个例子中sed由标准输入设备(即命令解释器,通常是以管道输入的形式)获得输入。在命令 行给出一个或多个文件名作为参数时,这些文件取代标准输入设备成为sed的输入。sed的输出将被送到标准输出(显示器)。因此:
 cat filename | sed ‘10q‘         # 使用管道输入
 sed ‘10q‘ filename               # 同样效果,但不使用管道输入
 sed ‘10q‘ filename > newfile     # 将输出转移(重定向)到磁盘上

 

括号语法:前面的例子对sed命令基本上都使用单引号(‘...‘)而非双引号("...")这是因为sed通常是在Unix平台上使用。单引号 下,Unix的shell(命令解释器)不会对美元符($)和后引号(`...`)进行解释和执行。而在双引号下美元符会被展开为变量或参数的值,后引号 中的命令被执行并以输出的结果代替后引号中的内容。而在“csh”及其衍生的shell中使用感叹号(!)时需要在其前面加上转义用的反斜杠(就像这 样:\!)以保证上面所使用的例子能正常运行(包括使用单引号的情况下)。DOS版本的Sed则一律使用双引号("...")而不是引号来圈起命令。

 

‘\t‘的用法:为了使本文保持行文简洁,我们在脚本中使用‘\t‘来表示一个制表符。但是现在大部分版本的sed还不能识别‘\t‘的简写方式,因此当 在命令行中为脚本输入制表符时,你应该直接按TAB键来输入制表符而不是输入‘\t‘。下列的工具软件都支持‘\t‘做为一个正则表达式的字元来表示制表 符:awk、perl、HHsed、sedmod以及GNU sed v3.02.80。

 

不同版本的SED:不同的版本间的sed会有些不同之处,可以想象它们之间在语法上会有差异。具体而言,它们中大部分不支持在编辑命令中间使用标签 (:name)或分支命令(b,t),除非是放在那些的末尾。这篇文档中我们尽量选用了可移植性较高的语法,以使大多数版本的sed的用户都能使用这些脚 本。不过GNU版本的sed允许使用更简洁的语法。想像一下当读者看到一个很长的命令时的心情:
 sed -e ‘/AAA/b‘ -e ‘/BBB/b‘ -e ‘/CCC/b‘ -e d

 

好消息是GNU sed能让命令更紧凑:
 sed ‘/AAA/b;/BBB/b;/CCC/b;d‘      # 甚至可以写成
 sed ‘/AAA\|BBB\|CCC/b;d‘

 

此外,请注意虽然许多版本的sed接受象“/one/ s/RE1/RE2/”这种在‘s‘前带有空格的命令,但这些版本中有些却不接受这样的命令:“/one/! s/RE1/RE2/”。这时只需要把中间的空格去掉就行了。

 

速度优化:当由于某种原因(比如输入文件较大、处理器或硬盘较慢等)需要提高命令执行速度时,可以考虑在替换命令(“s/.../.../”)前面加上地址表达式来提高速度。举例来说:
 sed ‘s/foo/bar/g‘ filename         # 标准替换命令
 sed ‘/foo/ s/foo/bar/g‘ filename   # 速度更快
 sed ‘/foo/ s//bar/g‘ filename      # 简写形式

当只需要显示文件的前面的部分或需要删除后面的内容时,可以在脚本中使用“q”命令(退出命令)。在处理大的文件时,这会节省大量时间。因此:
 

sed -n ‘45,50p‘ filename           # 显示第45到50行
 sed -n ‘51q;45,50p‘ filename       # 一样,但快得多

 

SED总结

标签:

原文地址:http://www.cnblogs.com/x113/p/4679131.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!