美文网首页
sed学习笔记

sed学习笔记

作者: 1519f8ccc7b0 | 来源:发表于2017-06-01 11:16 被阅读0次

1 什么是sed

sed是unix下的面向字符流的编辑器,即stream editor, 它是面向行的,以行为单位进行处理,同时,sed是非交互式的,一旦执行便要处理完整个文件。
sed起源于ed,而awk起源于sed和grep。

sed可以用来完成:

  1. 在一个或多个文件上自动实现编辑操作;
  2. 简化在多个文件执行相同的编辑处理工作;
  3. 编写文本转换工作;

sed的四种主要应用场景:

  1. 对同一文件进行多重编辑
  2. 改变一组文件
  3. 提取文件内容
  4. 编辑工作转移

2 sed的基本操作

2.1 命令格式

sed [options] script inputfile
常用选项:
-n 阻止输入行的自动输出。无该参数时,在脚本执行完成后,自动输出模式空间中的内容;
-f 指定脚本文件名

注意:

  • 需要用大括号{}把过程括起来
  • 需要用单引号''将指令括起来
  • 需要用斜杠//将正则表达式括起来

2.2 模式空间和暂存空间

sed只读取输入文件的内容,但是并不改变文件中的内容,它通过维护一种模式空间,即一个工作区域或者叫做临时缓冲区,来放置从文件中读取的内容,并在模式空间中对内容进行编辑。
sed一次从文件中读取一行内容放入模式空间。这样做的好处是sed在读取非常大的文件时不会出现问题。

2.3 基本sed命令

注释

注释行的第一个字符必须是#
示例:

#这是一行sed注释
替换s

格式:
[address]s/pattern/replacement/flags
用途:
替换符合目标模式的的字符串

其中/为定界符,当pattern中包含/时,如果不想转义,可以使用其他字符如!作为定界符来避免转义:s!/usr/mail!/usr2/mail!

flags的可选值有:

n 1-512之间的数字,表示对本模式中指定模式第n次出现的情况进行替换,
其中$代表最后一行。
g 对模式空间的所有出现情况进行全局更改。
p 打印模式空间的内容。
w file 将模式空间的内容写入file

不指定flags时,默认flags为1,即替换第一次符合的情况。
flag可以组合使用,只要有意义就可以,如gp表示对行进行全局替换并打印该行。

replacement是一个字符串,用来替换与正则表达式匹配的内容。在replacement部分,只有下列字符有特殊含义:

& 代表匹配的正在表达式的内容
\n匹配第n个子串(n是一个数字),这个子串在pattern中用\(\)指定。
\ 转义字符

删除d

格式:
[address]d
用途:
删除符合匹配模式的字符串所在的整行,并重新读取下一行进入模式空间,将脚本执行流跳转到第一行,重新开始新一轮。

删除命令采用一个地址,如果行匹配这个地址就删除模式空间的内容。
删除命令还可是一个可以改变脚本中的控制流的命令。删除命令会导致读取新的输入行,并使脚本回到开头的第一行开始执行(即开始新一轮执行)
示例:
/^$/d 删除空行
/^$/!d 删除非空行
1d 删除第一行
$d 删除最后一行

追加、插入和更改

追加:

[line-address]a\
text

插入:

[line-address]i\
text

更改:

[line-address]c\
text

这些命令中的每一个都要求后面跟一个反斜杠\用于转义第一个行尾。text必须从下一行开始。要输入多行文本,每个连续的行都必须用反斜杠结束,最后一行例外。

替换y

格式:
[address] y /abc/xyz/
作用:
按位置将字符串abc中的每个字符,都转换成字符串xyz中的等价字符。
注意:y命令将影响整个模式空间的内容。
示例:
大小写转换:

y/abcdefghijk/ABCDEFGHIJK
打印p

格式:
p
作用:
输出模式空间的内容,它不会清空模式空间的内容也不会改变脚本的控制流。
示例:
在行改变前后打印之

/^\.Ah/{
p
s/"//g
s^\.Ah //p
}

注意:打印命令被提供给替换命令。替换命令的打印标志不同于打印命令,因为它是以成功的替换为条件的打印。

root$ ls
sedtxt  txt
root$ cat txt

Hi
THis is a test file,
.Ah 
haha this is end.
root$ cat sedtxt
/^\.Ah/{
p
s/"//g
s/^\.Ah //p
}
root$ sed -f sedtxt txt

Hi
THis is a test file,
.Ah 


haha this is end.
打印行号=

格式:[line-address]=
作用:打印行号
示例:

root$ cat sedtxt
/^\.Ah/{
=
p
s/"//g
s/^\.Ah //p
}
root$ sed -nf sedtxt txt
4
.Ah 

下一行n

格式:[address]n
作用:输出模式空间中的内容,然后读取输入的下一行,而不用返回到脚本的顶端。
示例:删除符合以.Ah开始,且下一行为空行的模式中的空行

root$ cat nSed txt
/^\.Ah/{
n
/^$/d
}

Hi
THis is a test file,
.Ah 

haha this is end.
root$ sed -f nSed txt

Hi
THis is a test file,
.Ah 
haha this is end.
退出q

格式:[line-address]q
作用:停止读取新的输入行,脚本结束
示例:找到第一个Hi
找到第三行

root$ sed '/Hi/q' txt

Hi
root:sed fanshifeng$ sed '3q' txt

Hi
THis is a test file,

3 高级sed命令

高级命令分为3个组:

  1. 处理多行模式空间(N、D、P);
  2. 采用保持空间来保存模式空间的内容并使它可以用于后续的命令(H、h、G、g、x);
  3. 编写使用分支和条件指令的脚本来更改控制流(:、b、t);

3.1 多行模式空间

基本命令只能处理单个输入行的匹配,很难处理一个横跨了两行的匹配模式,为了解决这一问题,sed允许通过多行命令(N、D、P)来处理多行匹配的情况。使用这些命令可以创建出多行模式的空间。
在多行模式空间中,元字符^匹配模式空间中的第一个字符,元字符$匹配模式空间中的最后的换行符。

追加一行N

多行命令Next通过读取新的输入行,并将它追加到模式空间现有内容之后,两行之间以换行符分割,可以通过\n来匹配换行符。
Nn命令不同,next输出模式空间的内容,然后读取新的输入行。

$!N对最后一行不执行Next命令,防止在奇数行时,出现最后一行无法输出的情况。

示例:将Owner and Operator Guide替换为Installation Guide

root$ cat NextSed txt
/Operator$/{
N
s/Owner and Operator\nGuide/Installation Guide/
}
Consult Section 3.1 in the Owner and Operator
Guide for a description of the tape drives
available on your system.
root$ sed -f NextSed txt
Consult Section 3.1 in the Installation Guide for a description of the tape drives
available on your system.

这里有一个小问题,替换后的内容由两行变为了一行,我们再对它进行一些优化

root$ cat NextSed txt
/Operator$/{
N
s/Owner and Operator\nGuide/Installation Guide\
/
}
Consult Section 3.1 in the Owner and Operator
Guide for a description of the tape drives
available on your system.
root$ sed -f NextSed txt
Consult Section 3.1 in the Installation Guide
 for a description of the tape drives
available on your system.
多行删除D

作用:删除模式空间中直到第一个嵌入的换行符的这部分内容。它不会导致读入新的输入行,而且它会返回到脚本的顶端,重新开始执行脚本内容。

示例:删除多行空行,只保留一个空行

root$ cat txt

Consult Section 3.1 in the Owner and Operator


Guide for a description of the tape drives



available on your system.The Operator


The end!
root$ cat sedtxt
/^$/{
N
/^\n$/d
}
root$ cat sedtxt2
/^$/{
N
/^\n$/D
}
root$ sed -f sedtxt txt

Consult Section 3.1 in the Owner and Operator
Guide for a description of the tape drives

available on your system.The Operator
The end!
root$ sed -f sedtxt2 txt

Consult Section 3.1 in the Owner and Operator

Guide for a description of the tape drives

available on your system.The Operator

The end!

NOTE:利用了D命令只删除换行符前的内容而不是全部内容的特性。

多行打印P

作用:输出多行模式空间的第一部分,直到第一个嵌入的换行符为止。


重要:在执行完脚本的最后一个命令之后,模式空间的内容自动被输出,除非使用-n抑制这个动作。因此,当默认的输出被抑制或者脚本中的控制流被更改,以致不能到达脚本的底部时,需要使用打印命令P或者p


Print命令经常出现在Next命令之后和Delete命令之前。这3个命令能建立一个输入/输出循环,用来维护两行的模式空间,但是一次只输出一行。这个循环的目的是只输出模式空间的第一行 ,然后返回到脚本的顶端将所有的命令应用于模式空间的第二行。

保持命令

H:将模式空间的内容追加到保持空间
h:将模式空间的内容复制到保持空间(替换掉原有内容)
G:将保持空间的内容追加到模式空间
g:将保持空间的内容复制到模式空间(替换掉原有内容)
x:交换保持空间和模式空间的内容(替换掉原有内容)

示例:交换两行的位置

root$ cat num numSwap
1
2
3
4
5
6

/.*/{
h
N
s/.*\n//
G

}
root$ sed -f numSwap num
2
1
4
3
6
5

另一种方式:

root$ cat num numSwap
1
2
3
4
5
6

/.*/{
N
s/\(.*\)\n\(.*\)/\2\
\1/
}
root$ sed -f numSwap num
2
1
4
3
6
5

注意:这个替换命令
s/\(.*\)\n\(.*\)/\2\ \1/
匹配模式空间的2个部分,1)嵌入的换行符之前的所有字符,2)嵌入的换行符之后的素有内容。这个命令的替换部分回调被保存的部分,并按照不同的顺序重新组合他们,并通过换行符进行连接。

跳转命令b

格式:[address]b[label]
如果没有给出标签label,控制被转移到脚本的末尾。
标签格式::labelName
模式没有任何参数的跳转命令将跳至脚本末尾。

测试命令t

格式:[address]t[label]
用途:如果在当前匹配地址的行上进行了成功的替换,那么test命令就转到标签处。因此它隐含了一个条件分支。
如果没有给出标签label,控制被转移到脚本的末尾。

4 sed应用

使用sed模拟head

root$ cat num
1
2
3
4
5
6

root$ sed '5q' num
1
2
3
4
5

使用sed模拟tail

sed -e ':a' -e '$q;N;11,$D;ba' num

没看明白...

使用sed模拟两个模式的grep

root$ cat gredSed 
#!/bin/bash
search=$1

shift
for file
do
sed '
/'"$search"'/b
N
h
s/.*\n//
/'"$search"'/b
g
s/ *\n/ /
/'"$search"'/{
g
b
}
g
D
' $file
done

5 命令汇总

相关文章

网友评论

      本文标题:sed学习笔记

      本文链接:https://www.haomeiwen.com/subject/wgmsfxtx.html