sed命令

Posted perfy576

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sed命令相关的知识,希望对你有一定的参考价值。

sed编辑器是一个流式编辑器,其功能是:一次性从输入中读取一行数据,然后根据命令匹配的数据和修改命令,修改流中的数据,最后将新的数据输出到标准输出中.

1 选项

sed命令选项:

  1. -e ‘script‘:引号中为要处理的方式和匹配的模式,也就是修改命令,是sed最重要的部分.选项通常可以省略.引号也是可以省略的.但通常还是加上为好.
  2. -f filename:修改命令存储在filename
  3. -n:sed命令,默认所有的处理过和未处理的行都打印出来,而-n则表示不要打印
  4. 最后一个选项,没有名称,表示数据的输入文件.

2 命令命令

单条命令:

按照出现的选手顺序分为:

[分隔符]行寻址[分隔符]修改方式[分隔符][数据匹配模式][分隔符][修改后数据][分隔符][修改的标记]

这其中有很多部分,根据需要,可以没有,除了修改方式以外,其他的都可以没有.

分隔符通常是/

2.1 行寻址

行寻址表示那些行需要被处理,也就是说,即使有些行满足需要修改的条件,但是不在行寻址的范围内,那么也是不能被修改的.

行寻址可以使用指定特定的行,或是一个范围,直接以数字开始例如:单独一个1就表示第一行,2,5表示第2~5行.3~$表示从第3行开始到结束.

例如d命令是删除,那么sed 1d /etc/passwd就是删除第一行,然后输出了其他的行.sed ‘3,$d‘ /etc/passwd就是只输出前两行.(这里不加引号)就会出错

行寻址还可以是正则表达式,正则表达式寻址则需要使用分隔符包裹起来.

例如:sed ‘/root/d‘ /etc/passwd就是删除所有含有root的字符.当然还可以包含更复杂的正则表达式.

duoge如果行寻址模式有两个,以逗号分割,那么在遇到第一个的时候会打开,直到遇到第二个会关闭寻址.这个范围内的行才会被修改.但是关闭以后,又遇到第一个,还是会打开,循环往复.

2.3 修改方式

修改方式指明了,对于行寻址范围内的行,如果行中数据与匹配模式中匹配,那么要以何种方式进行修改.

  1. s:替换,如果行在行寻址范围内,并且行的数据中又满足数据匹配模式的,那么就将匹配到的数据,修改为"修改后数据",只有匹配到的数据才会被修改,其他数据不会更改
  2. d删除
  3. i行前添加一行
  4. a行后添加一行
  5. c修改,与替换的不同在于,修改是只要该行中有数据符合匹配模式,那么就会用"修改后数据"替换整行,而替换只是替换匹配的字符.
  6. y转换,要求数据匹配模式和修改后数据的字符相同,例如y/123/456/那么会用4替换1,5替换2,6替换3.是字符级别的替换.
  7. q:表示,遇到指定的数据就退出

ubuntu中,c命令貌似有问题?

技术分享图片

应该是只有行寻址,寻址以后直接替换为c后面的数据,没有数据匹配模式和分隔符.

2.3 数据匹配模式

该部分是正则表达式,当然也可以是确定的数据,如果为空,那么表示所有.

其中dq不能指定该部分了.

其他的修改方式,只要有"修改后数据",那么数据匹配模式部分就需要存在.

2.4 修改后数据

用于根据修改方式,对每行数据进行操作的.

2.4.1 匹配数据引用

其中&表示数据匹配模式中匹配到的数据,可以在该部分中,使用&来引用.

例如:

echo this is a test line | sed 's/w+/[&]/g'

技术分享图片

2.4.2 多处匹配数据引用

当数据匹配模式中是使用()包裹的多个正则表达式时,每个正则表达式都能匹配到一份数据,,那么1,2...就表示第几个正则匹配到的字符串.可以在该部分中直接引用:

技术分享图片

2.5 修改标记

该部分,是对修改的过程和修改的结果进行控制:

  1. p:打印修改过的行,通常配合-n选项,先关闭输出,然后在使用p打开输出
  2. w file:输出结果写入指定文件中
  3. g:当一行中,有多个数据符合数据匹配模式的时候,那么g表示全都修改,否则只修改第一个.当使用 数字g则表示从指定第数字个符合的项开始修改

sed ‘s/test/trial/gw out.txt‘ input.txt:从input.txt中输入,并将其中每行的所有的test单词改变为trial,注意,这里只会将修改过的语句输出到out.txt,而所有修改过还未修改过的语句都会输出在终端上.

2.6 转义和分隔符

书上说,可以使用任意字符替换分隔符,但是,我并没有发现可以使用别的.所以分隔符就是/

3 多个命令

当一次需要对符合条件的行执行多个命令的时候,其格式是:

address {
    ..;
    ..;
    ..
}

也就是行寻址可以提出来,然后在花括号中,写多个处理语句,使用分好分割.

3.1 保持空间

在sed中,当前正在处理的行,所处的缓存称为模式空间,也就是说,每行数据会被读入到模式空间以后,才会使用处理命令进行处理.

sed中还有一个叫做保持空间的缓存区域,可以用来保存数据.该缓存空间,相当于给程序员提供了一块可以倒腾数据的位置.

在保持空间和模式空间之间进行操作的命令为:

  1. h:模式空间的内容复制到保持空间
  2. H:模式空间的内容追加到保持空间
  3. g:保持空间中的内容复制到模式空间
  4. G:保持空间中的内容复制到模式空间
  5. x:交换两个空间中的数据

这5个命令,需要在单独的一行中:

例如sed /first/{H;p} input.txt,这个命令的的作用就是把所有包含first单词的行都追加到了保持空间中,然后打印了当前模式空间的行,因此在最终执行完毕之前,保持空间中保存可所有含有first的行.

4 多行合并

4.1 下一行

当需要处理的数据为多行的时候,一般指的是,当本行数据匹配到以后,需要处理本行后面的一行,那么可以使用n命令.

其作用是,在本行处理中,读取下一行数据.当本行处理完以后,还是会去处理下一行.也就是说n命令只是读取下一行,并不是跳过下一行.

技术分享图片

本来应该输出1和3,但是因为n命令的原因,输出了他们对应的下一行,也就是2和4.

多个n是可以重复执行的:

技术分享图片

4.2 合并行

当需要将本行和下一行合并在一起,进行处理的时候,就需要使用N命令.

该命令,是将本行数据和下一行数据合并在一起,进行处理,但是第一行后面的回车换行是不会被删除的.只是合并在一起了.和n不一样,使用N会跳过合并了的行

技术分享图片

在第一行数据输出的时候,将第二行合并在第一行里面,因此匹配到了2,所以输出1和2,接下来是处理第3行,因为第二行已经被合并在第一行了.

在合并以后,使用p打印的时候,是打印合并后的数据,而使用P则可以打印合并前第一行的数据.

d同上,而D则只删除合并前的第一行数据.

n一样,N可以一起使用.

5 分支控制

5.1 !取反

感叹号!是简单的取反命令,一般来说是条件!命令b:表示当条件不符合的时候去执行命令,符合的时候不执行.

技术分享图片

本来应该是输出1和3,但是使用了!,取反,因此2和4被输出.

其实,行寻址和数据匹配模式,都可以看作是正操作,而加上!则是反操作:

技术分享图片

如果不是结尾,那么就将模式空间中的数据添加保持空间中,当是最后一行的时候,就交换模式空间和保持空间,然后当是最后一行的时候,就输出模式空间的数据.因为第一个是追加,因此第一行是空行.

5.2 b分支

格式为:寻址或是匹配模式 b label; ...; :label 命令,注意label之前有个冒号,并且和后面命令之间只有空格分割.如果没有b指定的label,那么就相当于什么都不执行

技术分享图片

5.3 t 命令

t命令格式为:命令1 ;t; 命令2,如果命令1执行了,那么t后面的不去执行,如果命令1没有执行,那么就去执行t后面的.

技术分享图片

当匹配到1那么就不会执行t后面的了.

6 在脚本中使用sed

通常的格式为:

var=$(echo str | sed ..)

7 sed工具

7.1 每行数据后面添加一个空行

sed ‘G‘ input.txt

技术分享图片

原因在于保持空间初始时有一个空行,G命令,是将保持空间中的数据添加到模式空间中,因此就会在模式空间后面添加一个空行.

7.2 删除空行

sed ‘/^$/d‘

技术分享图片

^$正则能够匹配空行.

7.3 加行编号

=命令,可以为数据加上行编号.但是形式是这样的:

技术分享图片

在原来数据行之前插入一行,然后标号.

这个结果,可以使用N命令,合并,然后删除 回车,替换为一个空格即可:

技术分享图片

以上是关于sed命令的主要内容,如果未能解决你的问题,请参考以下文章

linux 特殊符号怎样用sed替换

linux shell sed命令的问题!

VSCode自定义代码片段——git命令操作一个完整流程

Mac 下如何使用sed -i命令

VSCode自定义代码片段——cli的终端命令大全

sed 错误:sed:-e 表达式 #1,字符 22:未终止的 `s' 命令