三剑客之sed

sed工作原理

  sed中文名叫流编辑器,大致意思是流动的方式编辑文本,即不需要人为手动打开文本进行编辑,通过sed自身的一些相应规则对文件进行匹配编辑,原理如下:

  • sed编辑器逐行处理,并且将结果发送到屏幕。
  • sed把当前正在处理的行保存在一个临时缓存区,这个缓存区称为模式空间或者临时缓存
  • sed还有一个空间,叫暂存缓存区或者保持空间;暂存缓存区辅助临时缓存区做文本处理。
  • sed处理完模式空间的行后就把该行从模式空间中删除,然后进行读取下一行至模式空间
  • sed处理完模式空间的行后就把内容输出至屏幕,并且退出sed程序。
  • 模式空间:可以想成工程里面的流水线,数据之间在它上面进行处理。
  • 保持空间:可以想象成仓库,我们在进行数据处理的时候,作为数据的暂存区域。

sed与正则表达式

sed在查找文件内容时也需要正则表达式,默认使用正则表达式(RE),正则表达式是括在斜杠之间的模式,用于查找和替换。

示例

sh-4.2# sed -n '/RE/p' filename

如果要把正则表达式分隔符(/)改成其他字符,比如c,只要在这个字符前加一个反斜杠,在该字符后加入正则表达式,最后再跟上该字符即可;示例如下:

sh-4.2# sed -n '/love/p' filename
# 改成如下内容:
sh-4.2# sed -n 'clovecp' filename

  这里的love就是正则表达式。
  名词说明一下:/(斜杠),(反斜杠)

sed -n '/12/10/04/p' filename
sed -n 'x12/10/04xp' filename

# 说明:
# 如果斜杠本身是正则表达式的一部分,必须在它前面加上反斜杠,以免和用作分隔符的斜杠混淆。
# x顶替斜杠成为分隔符,便于在正则表达式中包含斜杠。

sed定址

  • sed定址用于决定对哪些行进行编辑;定址的形式可以有数字、正则表达式或者二者的结合。如果没有定址,sed默认处理所有行。
  • 如果sed定址用的是数字,则这个数字表示行号。美元符号可以用来指输入文件的最后一行。如果给出的是逗号分隔的两个行号,那么需要处理的地址就是这两行之间的范围。范围可以是数字、正则表达式及两者的结合。
  • sed可以根据定址进行打印、删除、修改等操作。

 

格式:sed 'command' filename

范例
1、 sed '1,3d' myfile
2、 sed -n '/[Jj]ohn/p' datafile

说明
1、 删除文件第1至第三行的内容
2、 只打印文件中包含John或者john关键字的行

 

sed命令与选项

sed范例

本文中的范例使用文件datafile作为输入文件。内容如下:

sh-4.2# cat datafile
northwest    NW    Charles Main           3.0    .98    3    3
western      WE    Sharon Gray            5.3    .97    5    23
southwest    SW    Lewis Dalsass          2.7    .8     2    18
southern     SO    Suan Chin              5.1    .95    4    15
southeast    SE    Patricia Hemenway      4.0    .7     4    17
eastern EA   TB    Savage                 4.4    .84    5    20
northeast    NE    AM Main Jr.            5.1    .94    3    13
north        NO    Margot Weber           4.5    .89    5    9
central      CT    Ann Stephens           5.7    .94    5    13

范例1
打印匹配关键字'north'的行,并且静默输出(取消默认的打印操作)

sh-4.2# sed -n '/north/p' datafile

范例2
删除第三行内容

sh-4.2# sed '3d' datafile

范例3
删除第三行内容至最后一行

sh-4.2# sed '3,$d' datafile

范例4
所有包含模式'north'的行都被删除;其余的行被打印

sh-4.2# sed '/north/d' datafile

范例5
将文件中所有west的关键字更换成north

sh-4.2# sed 's/west/north/g' datafile

范例6
将文件中所有west的开头的关键字更换成north,并且只打印该行

sh-4.2# sed -n 's/^west/north/p' datafile

范例7
将文件中所有两位数字结尾的行,在数字后面加上.5

sh-4.2# sed 's/[0-9][0-9]$/&.5/' datafile

范例8
文件中出现所有Hemenway的关键词都替换成Jones,只有发生改变的行才被打印。

sh-4.2# sed -n 's/Hemenway/Jones/gp' datafile

范例9
包含在圆括号里面的模式Mar作为标签1保存于特定的寄存器中。替换串可以通过1引用它,则Margot替换成Marianne。

sh-4.2# sed -n 's/(Mar)got/1ianne/p' datafile

范例10
紧跟在s命令后的字符就是查找串和替换串之间的分隔符。分隔符默认为正斜杠,但可以改变。无论什么字符(换行符、反斜杠除外),只要紧跟着s命令,就可以成为新的分隔符。这个方法在查找包含正斜杠的模式很方便,例如查找路劲或者日期。

sh-4.2# sed 's#3#88#g' datafile

范例11
打印模式'west'和模式'east'之间的所有行。如果west出现在east之后的某一行,则打印范围从west所在行开始,到下一个出现east的行或者文件末尾(如果前者未出现)

sh-4.2# sed -n '/west/,/east/p' datafile

范例12
打印从第五行到第一个以northeast开头的行之间的所有行。

sh-4.2# sed -n '5,/^northeast/p' datafile

范例13
修改模式'west'到模式'east'之间的所有行,将各行的行尾'$'替换成字符串'**VACA**'。换行符被移到这个新的字符串后面。

sh-4.2# sed '/west/,/east/ s/$/**VACA**/' datafile

范例14
选项-e用于进行多重编辑。第一重编辑删除1至3行。第二重编辑将Hemenway替换成Jones。因为是逐行进行这两项编辑(即这两个命令都在模式空间的当前行上执行),所以编辑命令的顺序会影响结果。例如,这两条命令执行的都是替换,则前一次替换会影响后一次替换。

sh-4.2# sed -e '1,3d' -e 's/Hemenway/Jones/' datafile

范例15
r命令读取文件的指定行。如果在文件datafile的某一行匹配到模式Suan,就在该行后读入文件newfile的内容。如果出现的Suan的不止一行,则出现在Suan的各个行后都读入newfile文件的内容。

# 示例文件
sh-4.2# cat newfile
----------------------------------------------
|*** SUAN HAS LEFT THE COMPANY*** |
----------------------------------------------

sh-4.2# sed '/Suan/r newfile' datafile

范例16
w命令把指定行写入文件。文件datafile中所有包含模式north的行都被写入到newfile中。

sh-4.2# sed -n '/north/w newfile' datafile

范例17
命令a用于追加。字符串--->THE NORTH SALES DISTRICT HAS MOVED<---被加在以north开头,north后跟一制表符的各行之后。用于追加的文本必须出现在追加命令的下一行上。sed要求a命令后跟一个反斜杠。如果要追加的内容不超过80个字符(即一行的最大内容),则除最后一行外,其他各行都必须用反斜杠结尾。

sh-4.2# sed '/^north	/a
--->THE NORTH SALES DISTRICT HAS MOVED<---' datafile

或者

sh-4.2# sed '/^north	/a --->THE NORTH SALES DISTRICT HAS MOVED<---' datafile

范例18
命令i是插入命令。如果在某一行匹配到模式eastern,i命令就在该行的上方插入命令中反斜杠后的文本。除了最后一行,插入的文本每一行都必须以反斜杠结尾。

sh-4.2# sed '/eastern/i
> NEW ENGLAND REGION
> ----------------------------------------' datafile

范例19
命令c是修改命令。该命令将完整的修改在模式空间中的当前行。如果模式eastern被匹配,c命令将用反斜杠后的文本替换包含eastern的行。除了最后一行之外,反斜杠对每一行插入的行都是必要的。

sh-4.2# sed '/eastern/c
> THE EASTERN REGION HAS BEEN TEMPORARILY CLOSED' datafile

范例20
如果在某一行匹配到模式eastern,n命令就指示sed用下一个输入行(即包含AM Main Jr.的那一行 )替换模式空间中的当前行,并用Archie替换该行中的AM,然后打印该行,再继续往下处理。

sh-4.2# sed '/eastern/{n; s/AM/Archie/;}' datafile

或者

sh-4.2# sed -e '/eastern/n' -e 's/AM/Archie/' datafile

范例21
y命令把第1至3行中的所有小写字母替换成大写字母。正则表达式元字符y命令不起作用。与替换分隔符一样,斜杠可以被替换成其他字符。

sh-4.2# sed '1,3y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' datafile

或者

sh-4.2# sed '1,3 s/[a-z]/u&/g' datafile 

范例22
将文件中的所有小写字母转换成大写字母。

sh-4.2# sed 's/[a-z]/u&/g' datafile

说明:查找串中可以用正则表达式,但是替换串中不能用正则表达式,只能用u;
u就是表示把第一个字符转化成大写字母。
U就是表示所有的大写字母。
&表示匹配前面正则表达式的那部分。

范例23
将文件中所有的大写字母转换成小写字母。

sh-4.2# sed 's/[A-Z]/l&/g' datafile

说明
l就是表示将所有的大写字母转换成小写字母
L就是表示所有的小写字母。

范例24
打印完第五行之后,q命令让sed程序退出。

sh-4.2# sed '5q' datafile

范例25
匹配模式'Lewis',并且用Joseph替换,然后用q命令退出sed程序。

sh-4.2# sed '/Lewis/{s/Lewis/Joseph/;q;}' datafile

范例26
将模式'northeast'的行放入到最后一行显示

sh-4.2# sed -e '/northeast/h' -e '$G' datafile

说明
sed处理文件时,会把文件的每一行都保存到模式空间(临时缓冲区)中。sed处理完每一行后,都会将其打印到屏幕上,除非该行被删除或者取消打印。之后,模式空间会被清空,下一输入行被保存进来,等待处理。本例中,包含模式northeast的行被找到之后,就被存放到模式空间里,h命令把它复制并且保存到另外一个特殊的缓冲区,这个特殊的缓冲区成为暂存缓冲区。在第二条指令中,sed读到最后一行($)时,G命令指令指示它从暂存缓冲区中读取这一行,将其放回到模式空间中,追加在模式空间内当前行(即文本的最后一行)的后面。简而言之:所有包含模式northeast的行都会被复制到暂存缓冲区中,并且追加到文本的末尾。

范例27
将包含模式'WE'的行,放入到模式'CT'后显示

sh-4.2# sed -e '/WE/{h;d;}' -e '/CT/{G;}' datafile

说明
如果找到模式WE,h命令将从模式空间复制行到暂存缓冲区。之后d命令将包含WE模式的行全部删除,即不再显示它。第二条指令将查找模式CT,然后G命令取出之前存放在暂存缓冲区中的内容投放到CT模式后。

范例28
将包含模式'northeast'的行,存放到暂存缓冲区,并且替换显示到文本的最后一行

sh-4.2# sed -e '/northeast/h' -e '$g' datafile

说明
本例中,包含模式'northeast'的行会被h命令复制到暂存缓冲区。在第二条sed指令中,sed读取到最后一行($)时,g指令指示它从暂存缓冲区中读入行,并且将其放回到模式空间,替换掉模式空间内当前行。简而言之:包含'northeast'的行被复制并用来替换文件的最后一行。

范例29
将包含模式'WE'的行复制到模式空间并且删除,替换包含'CT'模式的最后一行(不指定,默认替换所有)。

sh-4.2# sed -e '/WE/{h;d;}' -e '/CT/{$g}' datafile

说明
如果找到模式WE,h命令就将其复制到暂存缓冲区。d命令将模式空间中的WE模式删除。若匹配模式CT,则g命令将获取暂存缓冲区的备份并覆盖模式空间中的当前行。简而言之:所有包含WE模式的行将转移到包含CT的行上,并进行覆盖。

范例30
包含Margot的行被包含Patricia的行替换。

sh-4.2# sed -e '/Patricia/{h;}' -e '/Margot/{x;}' datafile

sed练习题1

以dateboot文件内容为例,内容如下:

Steve Blenheim:238-923-7366:95 Latham Lane, Easton, PA 83755:11/12/56:20300
Betty Boop:245-836-8357:635 Cutesy Lane, Hollywood, CA 91464:6/23/23:14500
Igor Chevsky:385-375-8395:3567 Populus Place, Caldwell, NJ 23875:6/18/68:23400
Norma Corder:397-857-2735:74 Pine Street, Dearborn, MI 23874:3/28/45:245700
Jennifer Cowan:548-834-2348:583 Laurel Ave., Kingsville, TX 83745:10/1/35:58900
Jon DeLoach:408-253-3122:123 Park St., San Jose, CA 04086:7/25/53:85100
Karen Evich:284-758-2857:23 Edgecliff Place, Lincoln , NB 92743:7/25/53:85100
Karen Evich:284-758-2867:23 Edgecliff Place, Lincoln, NB 92743:11/3/35:58200
Karen Evich:284-758-2867:23 Edgecliff Place, Lincoln, NB 92743:11/3/35:58200
Fred Fardbarkle:674-843-1385:20 Parak Lane, Duluth, MN 23850:4/12/23:780900
Fred Fardbarkle:674-843-1385:20 Parak Lane, Duluth, MN 23850:4/12/23:780900
Lori Gortz:327-832-5728:3465 Mirlo Street, Peabody, MA 34756:10/2/65:35200
Paco Gutierrez:835-365-1284:454 Easy Street, Decatur, IL 75732:2/28/53:123500
Ephram Hardy:293-259-5395:235 CarltonLane, Joliet, IL 73858:8/12/20:56700
James Ikeda:834-938-8376:23445 Aster Ave., Allentown, NJ 83745:12/1/38:45000
Barbara Kertz:385-573-8326:832 Ponce Drive, Gzary, IN 83756:12/1/46:268500
Lesley Kirstin:408-456-1234:4 Harvard Square, Boston, MA 02133:4/22/62:52600
William Kopf:846-836-2837:6937 Ware Road, Milton, PA 93756:9/21/46:43500
Sir Lancelot:837-835-8257:474 Camelot Boulevard, Bath, WY 28356:5/13/69:24500
Jesse Neal:408-233-8971:45 Rose Terrace, San Francisco, CA 92303:2/3/36:25000
Zippy Pinhead:834-823-8319:2356 Bizarro Ave., Farmount, IL 84357:1/1/67:89500
Arthur Putie:923-835-8745:23 Wimp Lane, Kensington, DL 38758:8/31/69:126000
Popeye Sailor:156-454-3322:945 Bluto Street, Anywhere, USA 29358:3/19/35:22350
Jose Santiago:385-898-8357:38 Fife Way, Abilene, TX 39673:1/5/58:95600
Tommy Savage:408-724-0140:1222 Oxbow Court, Sunnyvale, CA 94087:5/19/66:34200
Yukio Takeshida:387-827-1095:13 Uno Lane, Ashville, NC 23556:7/1/29:57000
Vinh Tranh:438-910-7449:8235 Maple Street, Wilmington, VM 29085:9/23/63:68900

问题1:把Jon的名字改为Jonathan

sh-4.2# sed 's/Jon/Jonathan/' databook

问题2:删除头3行

sh-4.2# sed '1,3d' databook

问题3:打印第5~10行

sh-4.2# sed -n '5,10p' databook

问题4:删除含有Lane的所有行

sh-4.2# sed '/Lane/d' databook

问题5:打印所有生日在十一月或十二月的行

sh-4.2# sed -n '/:1[12]//p' databook

问题6:在以Karen开头的行末尾加上3颗星

sh-4.2# sed 's/^Karen.*$/&***/' databook

问题7:将所有包含Jose的行都替换为JOSE HAS RETIRED

sh-4.2# sed '/Jose/c JOSE HAS RETIRED' databook

问题8:把Popeye的生日改为11/14/46,假定您不知道Popeye的生日,设法用正则式查找出来

sh-4.2# sed -r -n -e '/Popeye/{s:[0-9]?+/[0-9]?+/[0-9]?+:11/14/46:;p}' databook

问题9:删除所有空行

sh-4.2# sed '/^$/d' databook

问题10:写一个能完成下列任务的sed脚本

  1. 在第一行上方插入标题PERSONNEL FILE.
  2. 删除以500结尾的工资项。
  3. 把名字和姓的内容颠倒后,打印文件内容。
  4. 在文件末尾加上THE END。
sh-4.2# sed -f sed databook
sh-4.2# cat sed
1i PERSONNEL FILE
s/[0-9]*500$//
s/^(w*)s*(w*)/2 1/
$a THE END

sed练习题2

利用sed将下面文件全部在一行中打印输出。

sh-4.2# cat datafile 
1.1.1.1
1.1.1.1
1.1.1.1
1.1.1.1

sed ":a;N;s/
//g;ta" datafile
1.1.1.1    1.1.1.1    1.1.1.1    1.1.1.1

说明
N; N是sed的一个处理命令,追加文本流中的下一行到模式空间进行合并处理,因此是换行符可见
:a和ta是配套使用,实现跳转功能。t是test测试的意思。
另外,还有:a和ba的配套使用方式,也可以实现跳转功能。b是branch分支的意思。

sed ":a;N;s/
//g;$!ba" datafile
1.1.1.1 1.1.1.1 1.1.1.1 1.1.1.1

awk的解决方案

awk 'BEGIN{ORS=" "}{print}END{print "
"}' datafile

练习题3

利用sed将下面文件内容里面的空格全部替换成换行符

sh-4.2# cat datafile
1.1.1.1 1.1.1.1 1.1.1.1 1.1.1.1

sh-4.2# sed 's/ /
/g' datafile 

参考文档:

原文地址:https://www.cnblogs.com/guge-94/p/10445421.html