UNIT28 SEd Basic Usage

Stream Editor主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。以下介绍的是Gnu版本的Sed。

定址选定希望编辑的行的范围

$ sed -n p file

$ sed -n '2,$p'  file

$ sed ‘/music/=’ 打印行号

$ sed -n '3,+1p' file  

$ sed -n ‘/.*ing/!p’ install.log

把不含‘样式’的数据行删除

$ sed -n /lang/!p file

$ sed -n '5,/^test/p' file

$ sed '/his/,/her/s/$/*******/' file

末尾用*******替换

$ sed 's/erors/errors/' file

one errors, two erors.

$ sed 's/erors/errors/g' file

one errors, two errors.

.sed [option] [action]

1.option]:-nerfi

-n  :使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN的数据一般都会被列出到屏幕上。但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。

-e  :直接在指令列模式上进行 sed 的动作编辑;

-f  :直接将 sed 的动作写在一个档案内, -f filename 则可以执行 filename 内的sed 动作;

-r  :sed 的动作支持的是延伸型正则表达式的语法。(预设是基础正则表达式语法)

-i  :直接修改读取的档案内容,而不是由屏幕输出。

2.[action][n1[,n2]] function

①n1, n2 :不见得会存在,一般代表『选择进行动作的行数』,举例来说,如果我的动作是需要在 10 到 20 行之间进行的,则『 10,20[动作行为] 』

②function

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。

= :打印当前行号码。

# :把注释扩展到下一个换行符以前。

{} 在定位行执行的命令组

以下的是替换标记

g:表示行内全面替换。

p:表示打印行。

w:表示把行写入一个文件。

x:表示互换模板块中的文本和缓冲区中的文本。

y:表示把一个字符翻译为另外的字符(但是不用于正则表达式)

.经典范例

1.列出/etc/passwd的内容,并且打印行号,同时,请将第2~5行删除!,在第二行后面加入两行字,例如『Drink tea or .....』『drink beer?

# nl /etc/passwd | sed '2aDrink tea or ......\

> drink beer ?'

     1  root:x:0:0:root:/root:/bin/bash

     2  bin:x:1:1:bin:/bin:/sbin/nologin

Drink tea or ......

drink beer ?

     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin

#每一行之间都必须要以反斜线 \ 来进行新行的增加

#在 a 后面加上的字符串就已将出现在第二行后面啰!那如果是要在第二行前呢?

# nl /etc/passwd | sed '2i drink tea' 就对啦!

2.我想将第2-5行的内容取代成为『No 2-5 number』呢?

# nl /etc/passwd | sed '2,5cNo 2-5 number'

     1  root:x:0:0:root:/root:/bin/bash

No 2-5 number

     6  sync:x:5:0:sync:/sbin:/bin/sync

3.仅列出第 5-7

# nl /etc/passwd | sed -n '5,7p'

# sed '5,7p' (没加-n5-7行会重复输出)

4.我们可以使用 ifconfig来列出 IP,若仅要 eth0 IP时?

# ifconfig eth0

eth0      Link encap:Ethernet  HWaddr 00:51:FD:52:9A:CA

          inet addr:192.168.1.12  Bcast:192.168.1.255  Mask:255.255.255.0

          inet6 addr: fe80::250:fcff:fe22:9acb/64 Scope:Link

.....(以下省略).....

# 其实,我们要的只是那个 inet addr:..那一行而已,所以利用 grep 与sed 来捉

# ifconfig eth0 | grep 'inet ' | sed 's/^.*addr://g' |  sed 's/Bcast.*$//g'

192.168.0.189

# 您可以将每个管线 (|) 的过程都分开来执行,就会晓得原因啰!

5./etc/man.config中,有MAN的设定取出来,但不要说明内容

# cat /etc/man.config | grep 'MAN'| sed 's/#.*$//g' | sed '/^$/d'

# 每一行当中,若有 # 表示该行为批注

6.利用 sed直接在 ~/.bashrc最后一行加入『# This is a test

# sed -i '$a # This is a test'  ~/.bashrc

# -i 参数可以让你的 sed 直接去修改后面接的档案内容喔!而不是由屏幕输出。

# 至于那个 $a  则代表最后一行才新增的意思

7.sed脚本文件(#开头的行为注释行)

行尾不能有空白或文本,一行中有多个命令用分号分隔。

8.按顺序执行{}括号里的命令

9.sed –r使用扩展正则

10.行号:=命令

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

# df -h|sed =|sed 'N;s/\n/ /'

1 Filesystem            Size  Used Avail Use% Mounted on

2 /dev/mapper/vol0-root

3                       7.8G  2.6G  4.9G  35% /

# df -h|sed = | sed 'N;s/\n/\t/'

1       Filesystem            Size  Used Avail Use% Mounted on

2       /dev/mapper/vol0-root

3                             7.8G  2.6G  4.9G  35% /

11.下一个:n命令

sed 'n;d'                              删除所有偶数行

sed -n '/regexp/{n;p;}'                显示匹配行的下一行

sed 'n;n;n;n;n;n;n;d;'                 其他sed, # 删除8的倍数行

sed -n '3,${p;n;n;n;n;n;n;}'           从第3行开始,每7行显示一次

sed '/test/{ n; s/aa/bb/; }' file      移到匹配行的下一行替换并替换

[address1 ,[address2]]N最多两个地址    添加一笔资料在pattern space 内

sed -e 'N' -e 's/\n/ /' input.dat       每两行连成一行,类似paste

The UNIX Operating System

原input.dat 的内容如下:

The

UNIX Operating System

sed '/./=' file | sed '/./N; s/\n/ /'   对所有行编号,但只显示非空行的行号

12.退出:q命令(最多配合一个地址参数)

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

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

sed -e '/zcs/q'                         遇到"zcs"就中止sed

13.标记:b:label命令

与函数参数b 可在sedscript 内建立类似BASIC 语言中GOTO 指令的功能。其中, 函数参数: 建立标记;函数参数b 将下一个执行的指令branch 到标记处执行。函数参数: 与b , 在script file 内配合的情况如下

编辑指令m1

:记号

编辑指令m2

[address1,[address2]]b [记号]

其中, 当sed执行至指令[address1,[address2]]b [记号] 时, 如pattern space 内的数据符合地址参数, 则sed将下一个执行的位置branch 至由:记号设定的标记处, 也就是再由"编辑指令m2" ... 执行。另外, 如果指令中参数b 后没有记号, 则sed将下一个执行的指令branch 到script file 的最后, 利用此可使sedscript 内有类似C 语言中的case statement 结构。

题目: 将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来作为停止循环的条件。当数据行有连续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

14.标记:t:label命令

执行t branch, 会先去测试其前的替换指令有没有执行替换成功。

script file 内的情况如下:

编辑指令m1

:记号

编辑指令m2

s/.../.../

[address1,[address2]]t [记号]

编辑指令m3

其中, 与参数b不同处在于, 执行参数t branch, 会先检查其前一个替换指令成功与否。如成功,则执行branch ; 不成功,则不branch , 而继续执行下一个编辑指令,

题目: input.dat文件中资料A1 替换成C1.C1替换成B1.B1 替换成A1

input.dat 檔的内容如下:

代号

B1

A1

B1

C1

A1

C1

说明: input.dat 文件中全部数据行只需要执行一次替换动作,但为避免数据被替换多次, 所以利用函数参数tsedscript 内形成一类似C语言中case statement 结构,使每行数据替换一次后能立即用函数参数t 跳离替换编辑。

sed

命令列:

sed

-e '{

s/A1/C1/

t

s/C1/B1/

t

s/B1/A1/

t

}' input.dat

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值