Chinaunix首页 | 论坛 | 博客
  • 博客访问: 42094
  • 博文数量: 8
  • 博客积分: 31
  • 博客等级: 民兵
  • 技术积分: 178
  • 用 户 组: 普通用户
  • 注册时间: 2011-12-09 12:29
文章分类

全部博文(8)

文章存档

2014年(6)

2013年(1)

2012年(1)

我的朋友

分类: LINUX

2014-08-23 22:11:30

每次都发现使用sed总会有些一知半解的地方,看不懂命令,但工作中又是使用最频繁的命令之一,因此借此全面学习下sed的所有用法,学习笔记分享出来,共享学习心得。
SED(Stream EDitor)为UNIX 系统上提供将编辑工作自动化的编辑器。

由于sed都以行为单位编辑文件,故其亦是行编辑器(line editor)。
sed 是一个非交互式上下文(context)编辑器,它被设计在下列三种情况下发挥作用:
1) 编辑那些对舒适的交互式编辑而言太大的文件。
2) 在编辑命令太复杂而难于在交互模式下键入的时候编辑任何大小的文件。
3) 要在对输入的一趟扫描中有效的进行多个‘全局’(global)编辑函数。

因为每次只把输入的某些行驻留在内存中,并且不使用临时文件,所以可编辑的文件的有效大小,只受限于输入和输出
要同时共存于次级存储的要求。

可以单独的建立复杂的编辑脚本并作为给sed 的命令文件。对于复杂的编辑,这节省了可观的键入和随之而来的错误。
从命令文件运行sed 高效于作者所知道的任何交互式编辑器,甚至包括能用预先写好的脚本驱动的编辑器。

相较于交互式编辑器而言,根本性的损失是缺乏相对地址(由于操作是每次一行的),和缺乏对命令如期运行的立即验证。

sed
可删除(delete)、改变(change)、添加(append)、插入(insert)、合并、交换文件中的数据行, 或读入其它文件的数据
到文件中, 也可替换(substuite)它们其中的字符串、或转换(tranfer)其中的字母等等

介绍所有sed
的函数参数的功能
函数参数功能

: label 建立script file 内指令互相参考的位置。
b label 将执行的指令跳至由: 建立的参考位置。
t label 先执行一替换的编辑指令, 如果替换成功;则将编辑指令跳至: label 处执行。

# 建立批注
{ } 集合有相同位址参数的指令。
! 不执行函数参数。
= 印出资料行数( line number )。 执行时, 行数将在数据输出前先输出。 批注:不能把=添加在D命令后,不然不会生效。
a\ 添加使用者输入的数据。       批注:使用a追加的数据应该在匹配行后插入或说成追加。
c\ 以使用者输入的数据取代数据。 批注:把匹配到的整行数据替换为c\后的内容。
i\ 插入添加使用者输入的数据行。 批注:注意i后面为什么要有一个斜线?使用i插入的数据应该在匹配行前插入。
    测试sed "5i   123" input.txt 和 sed "5i\   123" input.txt
    与之前a\ c\原理相同。
注:hold space为缓存空间,注:pattern space为模式空间,默认sed读取每行内容到模式空间

d 删除数据。
D 删除pattern space 内第一个newline(即换行符) 字母\n 前的数据。 
    函数参数D 与d 的比较如下:
    当pattern space 内只有一数据行时, D 与d 作用相同。
    当pattern space 内有多行资料行时
    D 表示只删除pattern space 内第一行资料; d 则全删除。
    D 表示执行删除后, pattern space 内不添加下一笔数据, 而将剩下的数据重新执行sed script ;
    d 则读入下一行后执行
    总结:注意D命令”pattern space 内不添加下一笔数据, 而将剩下的数据重新执行sed script“
          中的”剩下的数据重新执行sed script“,意思是执行了D命令,后面的命令不会再执行,
          而是重新从sed的命令块重头开始。
        如:sed "s/5/bb/;/[345a]/{N;s/[345a]/kk/g;D;P;}" input.txt
        当发现一行中有345a中任何一个字符时进入多命令集合{}中,并再读取下一行追加到模式空间(追加到第二行位置),
        再对模式空间中的两行数据进行替换345a中任何一个字符为kk,再把模式空间中第一行删除,
        此时D后面的P命令将不再执行,而是回到s/5/bb/处从左到右重新执行。
        注意在返回到s/5/bb处时模式空间中的数据仍未输出,一直保持在模式空间中。
   
h 拷贝数据从pattern space 至hold space 。表示暂存pattern space 的资料至hold space,
    并覆盖 hold space 内原来的数据,结束时, hold space 内数据会自动清除。
H 添加资料从pattern space 至hold space ,数据则是"添加(append)" 在hold space 原来数据后。

g 拷贝数据从hold space。表示与函数参数h 相反的动作,示将hold space 内资料放回pattern space 内。
    放回动作时, 数据盖掉(overwrite) pattern space 内原来的数据。
G 添加资料从hold space 至pattern space 。数据则是"添加(append)" 在pattern space 原来数据后。

x 交换hold space 与pattern space 内容。
    函数参数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

l 印出l 除可将资料中的nonprinting character 以ASCII码列出外, 其于均与函数参数p 相同。

n 读入下一笔资料。之前一行数据自动输出。
N 添加下一笔资料到pattern space, 数据行间以换行字符(embedded newline character)(\n)分隔。
    将下一行数据读入并添加在pattern space 内, 数据行间以换行字符(embedded newline character)分隔。
p 印出资料。sed 拷备一份pattern space 内容至标准输出
P 印出pattern space 内第一个newline 字母\n前的数据。P 与p , 除了面对的pattern space 内的数据行数不同外, 其它均相同。
q 跳出sed编辑。

r 读入它檔内容。
   sed "/test/r file" input.txt 把文件file中的内容读入存放到所有匹配到test的行后面。
w 写资料到它文件内。
   sed "/test/w file" input.txt  把文档中所有匹配到test的行写入到file文档中。

s 替换字符串。
y 转换(transform)字符。
    y /xyz.../abc.../
    指令中, /abc.../xyz.../(x、y、z、a、b、c 代表某些字符) 为y 的argument 。其中abc... 与xyz... 的字符个数必须相同。
    转换时, 将pattern space 内数据内的a 字符转换成x 字符、b 字符转换成y 字符、c 字符转换成z 字符...。
    如:
    sed -e "/Great/! y/a-d/1-4/" input.txt
    不存在Great的行中把abcd分别替换为1234。即:a替换为1,b替换为2,c替换为3,d替换为4。

以下只对高级用法做分析解读,对于基本用法就不做详细说明。
举例说明参数用法:
1、结合-n 和P 以及N 实现只输出奇数行信息:
$cat input.txt
1
2
3
4
$sed -n -e 'N' -e 'P' input.txt
1
3

2、指定行合并成一行(采用跳转参考:和t)
   如下把##之间的行都合并成一行,每行的内容以空格分隔:
$cat input.txt
#
1
2
3
#
4
5

$sed ":b;N;/#/! s/\n/ /;tb;P;D;" input.txt  (注:其中tb中只有在前一个编辑替换指令成功后才执行tb跳转到开头的:b处)
#
1 2 3
#
4 5

3、批量多次修改相同的配置,达到一次数量后结束(采用跳转参考:和b)
$cat input.txt
1
2
3
4
#
3
4
5
#
a
b
c
d
#
12
2
$sed '/1/{:p1;s/1/111/;/[1]\{30,\}/b;b p1;};/3/{:p2;s/3/333/;/[3]\{20,\}/b;b p2;};' input.txt
#说明:当一行中存在1时,把1替换为111,当该行中1的数量达到30以上时则退出该行的替换操作。后面数字3的修改原理相同。
1111111111111111111111111111111
2
333333333333333333333
4
#
333333333333333333333
4
5
#
a
b
c
d
#
11111111111111111111111111111112
2

4、学习t的另外一种用法,每行数据替换一次后能立即用函数参数t 跳离替换编辑
   如下,把其中A1 替换成C1、C1 替换成B1、B1 替换成A1
$cat input.txt
B1
A1
B1
C1
A1
C1
$sed 's/A1/C1/;t;s/C1/B1/;t;s/B1/A1/;t;' input.txt
A1
C1
A1
B1
C1
B1

5、把文本中某行替换为之前的某一行
$cat input.txt
#
1
2
3
#
4
5
a
#
12
2
$sed "/5/h;/12/x" input.txt    // 先把匹配到5的一行数据存放到hold space,当匹配到12行时,
                               //把hold space与pattern space中的值进行交换,即使用匹配到5的行替换匹配到12的行。
#
1
2
3
#
4
5
a
#
5
2

扩展1:
$sed "/5/h;/a/H;/12/x" input.txt
#
1
2
3
#
4
5
a
#
5
a
2
扩展2:
$sed "/5/H;/a/H;/12/x" input.txt 
说明:替换处5前多了一空行。是否说明缓存空间hold space中默认是存在一个空白行呢???
#
1
2
3
#
4
5
a
#

5
a
2

扩展3:
若如上分析,缓存空间默认存在一空行,那就可以利用来清空一行数据,但不是删除。
$sed "12/x" input.txt
#
1
2
3
#
4
5
a
#

2
如上:12所在行为清理为空行了。

6、如上使用h和x进行交换,但如果下一行仍然想用之前h存放到缓存的数据替换时,
  发现缓存空间中的数据已经被x替换为了上次交换时新行的数据。因此再学习下gG的用法吧。
$cat input.txt
1
2
3
4
#
3
4
5
#
a
b    
c
d
#
12
2
$sed "/5/h;/a/G;/12/g;" input.txt   注意:G是追加到模式空间,g是覆盖整个模式空间。
1
2
3
4
#
3
4
5
#
a
5
b
c
d
#
5
2


7、匹配行与其后一行相互交换。
$cat input.txt
#
1
2
3
#
4
5
a
#
12
2
$sed "5{h;N;G;D;}" input.txt   第五行与第六行相互交换。
#
1
2
3
4
#
5
a
#
12
2

8、学习了解D命令的使用原理
$cat input.txt
1
2
3
4
#
3
4
5
#
a
b
c
d
#
12
2
$sed "s/5/bb/;/[345a]/{N;s/[345a]/kk/g;D;p;}" input.txt  详细说明见上面D命令说明处。
1
2
kk
#
kk
bb
#
b
c
d
#
12
2

9、学习l打印与p,P的区别。
$cat input.txt
1
2
3
4
#
3
4
5
#
a
b    //4个空格
c    //注意c后面有一个tab键
d
#
12
2
$sed -n "l" input.txt
1$
2$
3$
4$
#$
3$
4$
5$
#$
a$
b    $
c\t$
d$
#$
12$
2$
由上可知,tab键可以使用\t代替。行结束符和换行符这里统一表示为$,空格是ASCII码,所以可以正常打印出来。

10、匹配到的所有行信息,存放到末尾。
$cat input.txt
1
2
3
4
#
3
4
5
#
a
b
c
d
#
12
2
$sed '/[2-4]/H;$G' input.txt
把所有2-4的数据行存放到缓存空间,最后行时取出追加到文本末尾。
1
2
3
4
#
3
4
5
#
a
b
c
d
#
12
2

2
3
4
3
4
12
2

11、一次性删除文档中多余的空白行,多行空白只保留一行。命令如下:
sed '/^\s*$/{N;/^\s*\n\s*$/D;}' input.txt

哎 一知半解真要命,终于一次性把sed完整的学习了。Fighting

 

阅读(2759) | 评论(0) | 转发(0) |
1

上一篇:shell中数字计算方法总结

下一篇:没有了

给主人留下些什么吧!~~