sed命令

1、简介

sed 全名为 stream editor,流编辑器,用程序的方式来编辑文本,功能相当的强大。是贝尔实验室的 Lee E.McMahon 在 1973 年到 1974 年之间开发完成,目前可以在大多数操作系统中使用,sed 的出现作为 grep 的继任者。与vim等编辑器不同,sed 是一种非交互式编辑器(即用户不必参与编辑过程),它使用预先设定好的编辑指令对输入的文本进行编辑,完成之后再输出编辑结构。sed 基本上就是在玩正则模式匹配,所以,玩sed的人,正则表达式一般都比较强。

sed是面向流的行编辑器,所谓面向流,是指接受标准输入的输入,输出内容到标准输出上。

2、sed如何处理数据?

sed在正常情况下,将处理的行读入模式空间(pattern space),脚本中的“sed-command(sed命令)”就一条接着一条进行处理,直到脚本执行完毕。然后该行被输出,模式(pattern space)被清空;接着,在重复执行刚才的动作,文件中的新的一行被读入,直到文件处理完毕。

3、什么是Pattern Space,什么是Hold Space?

pattern space相当于车间sed把流内容在这里处理。 hold space相当于仓库,加工的半成品在这里临时储存。 PS:你可以将pattern space看成是一个流水线,所有的动作都是在“流水线”上执行的;而hold space是一个“仓库”,“流水线”上的东东都可以放到这里。

4、为什么要使用sed高级命令(G、H、g、h、n、N、x)?

由于各种各样的原因,比如用户希望在某个条件下脚本中的某个命令被执行,或者希望模式空间得到保留以便下一次的处理,都有可能使得sed在处理文件的时候不按照正常的流程来进行。这个时候,sed设置了一些高级命令来满足用户的要求。

sed命令: g:[address[,address]]g 将hold space中的内容拷贝到pattern space中,原来pattern space里的内容清除 G:[address[,address]]G 将hold space中的内容append到pattern space\n后 h:[address[,address]]h 将pattern space中的内容拷贝到hold space中,原来的hold space里的内容被清除 H:[address[,address]]H 将pattern space中的内容append到hold space\n后 d:[address[,address]]d 删除pattern中的所有行,并读入下一新行到pattern中 D:[address[,address]]D 删除multiline pattern中的第一行,不读入下一行

PS:不论是使用G、g还是H、h,它们都是将hold space里面的内容“copy”到pattern space中或者将pattern space中的内容“copy”到hold space中。

附上英文的解释: The “h” command copies the pattern buffer into the hold buffer. The pattern buffer is unchanged. Instead of exchanging the hold space with the pattern space, you can copy the hold space to the pattern space with the “g” command. This deletes the pattern space. If you want to append to the pattern space, use the “G” command. This adds a new line to the pattern space, and copies the hold space after the new line.

4-1、示例:用sed模拟出tac的功能(倒序输出)

[root@ubuntu0006:/media] #cat mm

1
2
3
[root@ubuntu0006:/media] #tac mm
3
2
1

[root@ubuntu0006:/media] #sed '1!G;h;$!d' mm
3
2
1

ps:1!G第1行不 执行“G”命令(保持空间拷贝到模式空间),从第2行开始执行G命令。 $!d,文件读取最后一行不删除模式空间(保留模式空间),注意执行d命令还会读取新行到模式空间中。 注意显示pattern space中的内容。

[root@www ~]# sed [-nefr] [动作]
选项与参数:
-n :使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN 的数据一般都会被列出到终端上。但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。
-e :直接在命令列模式上进行 sed 的动作编辑;
-f :直接将 sed 的动作写在一个文件内, -f filename 则可以运行 filename 内的 sed 动作;
-r :sed 的动作支持的是延伸型正规表示法的语法。(默认是基础正规表示法语法)
-i :直接修改读取的文件内容,而不是输出到终端。

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

function:
a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~
c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
d :删除,因为是删除啊,所以 d 后面通常不接任何咚咚;
i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
p :列印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行~
s :取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 就是啦!

详细教程:https://www.runoob.com/linux/linux-comm-sed.html

sed -i 's/匹配字符/变成字符/g' test.txt

-i :直接修改读取的文件内容,而不是输出到终端。
s:或许是swap替换
g:global全局


sed -i "/匹配字符/,+2d/" test.txt
删除匹配字符行以及后面两行的内容


sed -i '/匹配字符/a\添加内容' test.txt
在匹配字符行后面添加一行内容
a代表after
i代表in front

使用sed删除匹配行及上下几行

1、sed介绍

基本正则表达式 关于正则表达式的内容挺多的,掌握好下文中提及的内容就能满足正常工作中的需要,如果是专门做正则编程的,可以去买本正则表达式的书籍来看好了^_^。只有多动手多练习,才是学开发编程的最好姿势。

  1. 符号"."

匹配任意一个字符,除了换行符,但是需要注意的是,在sed中不能匹配换行符,但是在awk中可以匹配换行符。类似shell通配符中的"?",匹配一个任意字符。

  1. 符号"*"

""表示前边字符有0个或多个。"."表示任意一个字符有0个或多个,也就是能匹配任意的字符。类似shell通配符中的"*",可以匹配任意字符。

  1. 符号"[]"

"[ ]"中括号中可以包含表示字符集的表达式。使用方法大概有如下几种。 [a-z]:表示a-z字符中的一个,也就是小写字母。 [0-9]:表示0-9字符中的一个,也就是表示数字。 [A-Z]:表示大写字母。 [a-zA-Z]:表示字符集为小写字母或者大写字母。 [a-zA-Z0-9]:表示普通字符,包括大小写字母和数字。 [abc]:表示字符a或者字符b或者字符c。 0-9:表示非数字类型的字符,^表示取反意思,只能放在中括号的开始处才有意义。 [-cz]:表示字符-或者字符c或者字符z,注意与[c-z]的区别,因为-符号没有放在e和f之间。

  1. 符号"^"

"^"表示行首的意思,也就是每一行的开始位置。在这里并不是上边字符范围中取反的意思,^符号只有在"[]"符号的开头处才能表示字符取反。

^abc:表示以abc开头的字符串abc。 ^abc.*:表示以abc开头的字符串abcxxx。

  1. 符号"$"

"$"表示行尾的意思,也就是每一行的结尾位置,很好理解,和"^"正好相反。

world$:表示以world结尾的字符串world,如果该行中间有world字符串是不符合匹配条件的。 ^$:表示空行。行首和行尾没有内容,可不就是空行嘛。

  1. 符号"\"

"\"表示是转义字符,和其它语言中用到的转义字符意义基本上是一样的。其实简单理解,就是把元字符转义为普通字符,比如"\"表示普通符号"\",把普通字符转换为特殊意义符号,比如"\n"表示把普通字符n转义为换行符。

  1. 符号"{}"

"{}"表示前边字符的数量范围,大概有三种用法,其实容易理解,看例子就知道了,但是必须注意要加上转义字符"\",否则不生效,表示为普通字符"{"或"}"。

{2}:表示前边字符的重复次数是2。 {2,}:表示前边字符的重复次数至少是2,也就是大于等于2。 {2,9}:表示前边字符的重复次数大于2但小于9。

  1. 符号"\<"和">"

"\<"表示匹配条件为词首的位置,理解上可以对比 "^" 行首。 举个例子,"nihao 1hello 2hello3 hello4"有这么内容的一行内容。 "\"匹配结果"nihao 1hello 2hello3 hello4",这种匹配方式用的不是太多,用到会用就OK。

三、扩展正则表达式 扩展正则表达式是在基本正则表达式中扩展出来的,内容不是很多,使用频率上可能没有基本正则表达式那么高,但是扩展正则依然很重要,很多情况下没有扩展正则是搞不定的。sed命令使用扩展正则需要加上选项-r。

  1. 符号"?"

"?":表示前置字符有0个或1个。

  1. 符号"+"

"+":表示前置字符有1个或多个。

  1. 符号"|"

"|":表示指明两项之间的一个选择。 abc|ABC:表示可以匹配abc或者ABC。

  1. 符号"()"

"()"表示分组,类似算数表达式中的()。子命令表达式中可以通过\1,\2,\3等来表示分组匹配到的内容。其实"()"也可以在基本正则表达式中使用的。

(a|b)b:表示可以匹配ab或者bb字串 ([0-9])|([0][0-9])|([1][0-9]):表示匹配0-9或者00-09或者10-19范围的字符。

  1. 符号"{}"

这里的"{}"和基本正则表达式中的大括号意义是一样的,只不过在使用时不用加"\"转义符号。

四、正则表达式的分类和应用 字符类 [Ww]hat .H[12345]

字符的范围 [a-z] [0-9] [Cc]hapter[1-9] [-+*/] [0-1][0-9][-/][0-3][0-9][-/][0-9][0-9]

排除字符类 0-9

重复出现的字符 [15]0* [15]00

字符的跨度 *与{n,m}

电话号码的匹配 [0-9]{3}-[0-9]{7,8}

分组操作 compan(y|ies)

sed参数

选项-r

sed命令的匹配模式支持正则表达式的,默认只能支持基本正则表达式,如果需要支持扩展正则表达式,那么需要添加-r选项。

选项-i

sed默认会把输入行读取到模式空间,简单理解就是一个内存缓冲区,sed子命令处理的内容是模式空间中的内容,而非直接处理文件内容。因此在sed修改模式空间内容之后,并非直接写入修改输入文件,而是打印输出到标准输出。如果需要修改输入文件,那么就可以指定-i选项。

将换行符替换为空格

https://my.oschina.net/shelllife/blog/118337

sed流编辑器是shell中处理文本内容的一大利器。sed命令从文本流中读取一行文本到模式空间中进行相应的命令、或脚本处理,因此在处理换行符时会有点特殊。

如:

echo "a,b,c,d" |sed 's/,/\n/g'|sed 's/\n/,/g'

是无法进行替换还原。

这跟sed的行处理方式有关,sed读取一行时,会先把换行符去掉,处理完后再添加上,所以是无法使用上面的命令进行换行符替换的,必须使用sed中的其它命令来完成。

tr命令可以实现

echo "a,b,c,d" |sed 's/,/\n/g'|tr -t '\n' ','

两个命令输出一致,但是sed命令的输出结尾有换行符,而tr命令的输出结尾没有换行符。

sed命令实现

下面是网上找到的一些用法,经实践效果是各不相同的,只有一种是完全可行的。

sed ':label;N;s/\n/:/;b label' filename
sed ':label;N;s/\n/:/;t label' filename

上面的两条命令可以实现将文件中的所有换行符替换为指定的字串,如命令中的冒号。命令的解释: :label; 这是一个标签,用来实现跳转处理,名字可以随便取(label),后面的b label就是跳转指令 N; N是sed的一个处理命令,追加文本流中的下一行到模式空间进行合并处理,因此是换行符可见 s/\n/:/; s是sed的替换命令,将换行符替换为冒号 b label 或者 t label b / t 是sed的跳转命令,跳转到指定的标签处 标签跳转和N的追加命令实现了每一行的不间断放入模式处理空间,从而不会漏掉每一个换行符,而没有标签的话跳转的话,就只能每两行替换掉一个换行符,对比效果:

$ echo "a,b,c,d" |sed 's/,/\n/g'|sed ':x;N;s/\n/,/;b x' a,b,c,d $ echo "a,b,c,d" |sed 's/,/\n/g'|sed 'N;s/\n/,/' a,b c,d 还有如下的一种命令的处理效果,也是无法实现换行符的替换。事实上$符号在sed中表示文本流中的最后一行,下面的处理结果我并不是很理解。 $ echo "a,b,c,d" |sed 's/,/\n/g'|sed 's/$/,/' a, b, c, d, PS:sed中的n命令和~地址表示

sed '8,80{n;n;n;d}' filename n表示读取文本流中的下一行到模式空间(N为追加),sed还是只处理一行。上面的命令理解:从第8行起(包含),一次读取9/10/11行,然后读取11行后,执行d命令,就是删除处理空间中的第11行,之后从12行开始,读取13/14/15, 删除15行,以此类推,直到第80行。 sed '11~4d' filename 该命令实现和上一个命令同样的功能,唯一的差别就是它直到文件结束,而无法指定结束行。

results matching ""

    No results matching ""