sed 基础命令
dear all ,自从一年多前开始python的旅程之后,突然觉得最近都没有怎么玩过sed 了,趁现在年纪还轻 哈哈,总结下sed 命令
sed, a stream editor 流编辑器,按行匹配/编辑处理文本文件 , 具体的sed介绍大家可以看看 sed手册 ,当然全英文的
这张图很有意思,大家可以领悟领悟(模式空间 pattern space),脚步中的内容改变了模式空间的内容
sed 和 awk 系列文章:
sed 基础命令:http://www.huangdc.com/109
sed 高级命令:http://www.huangdc.com/123
awk 基础命令 : http://www.huangdc.com/143
awk 高级命令:http://www.huangdc.com/146
sed 基础操作
1、命令行的语法
可以大致相同的方式调用sed和awk,命令行语法是:
command [options] script filename
几乎和所有的unix程序一样,sed和awk都可以从标准输入中取得输入并 将输出发送到标准输出。如果指定文件名filename,输入就取自那个文 件。输出包含处理后的信息
选项 options | 描述 |
---|---|
-e | 编辑随后的 |
-f | 跟随脚本中的文件名 |
-n | 阻止输入行的自动输出 |
-i | 直接修改读取的文件内容,而不是输出到终端 |
-r | sed 的动作支持的是延伸型正规表示法的语法。(默认是基础正规表示法语法) |
2、调用sed有两种方法:在命令行上指定编辑指令或者将他们放到一个文件中并提供这个 文件的名字
a、指定简单命令
可以在命令行上指定简单的编辑命令:
sed [-e] ‘instruction’ file_name
只有在命令行上给出多个指令时才需要用-e选项。它告诉sed将下一参数解释为指令。 当只有一个指令时,sed可以自己做决定。file_name 是需要处理的文本文件
b、脚本文件
在命令行上输入较长指令编辑脚本是不实际的。这就是创建包含编辑指令脚本文件的 原因。这种形式使用-f 选项来指定命令行上的脚本文件名字:
sed -f scriptfile file_name
将想要执行的所有编辑命令都放置在文件中。
简单看几个例子:
## 文件名 1.txt 及 简单内容
DcHuang@linux-fh38:~> cat 1.txt
11 22 33 44
55 66 77 88
## 一个指令:
DcHuang@linux-fh38:~> sed 's/66/huangdc/g' 1.txt
11 22 33 44
55 huangdc 77 88
## 多个指令:
DcHuang@linux-fh38:~> sed -e 's/66/huangdc/g' -e 's/33/huang/g' 1.txt
11 22 huang 44
55 huangdc 77 88
## 指令脚本文件(script.txt ):
DcHuang@linux-fh38:~> cat script.txt
s/66/huangdc/g
s/33/huang/g
DcHuang@linux-fh38:~> sed -f script.txt 1.txt
11 22 huang 44
55 huangdc 77 88
3、保存输出
只有将sed的输出重定向到另外一个程序/文件中,才能够捕获文件 中的输出。
sed -f sedscript list > newlist
阻止输入行自动显示(sed默认操作是输出每个输入行。-n 选项可以阻止自动输出。 当指定改选项时,每个要生成输出的指令都必须包含打印命令p )
sed 基础命令
命令的语法格式为:
行地址对于任何命令都是可选的,大多数sed命令能接受有逗号分隔的两个地址,这两个地址用 来标识行的范围
[address]command
或者 (单个行地址)
[line-address]command
或者 (用大括号进行分组以使其作用于同一个地址)
address{ command1 command2 }
先来看看基本命令有哪些,然后再一个一个举例
命令(小写字母) | 备注 |
---|---|
s | 替换 |
d | 删除 |
a、i、c | 追加、插入和更改 |
l | 列表 |
y | 转换 |
p、= | 打印/打印行号 |
n | 下一步(读取下一行) |
r、w | 读和写文件 |
q | 退出 |
1、替换
替换命令的详细用法
[address]s/pattern/replacement/flags
这里修饰替换的标志flags是:
标志flags | 含义 |
---|---|
n | 1-512之间的一个数字,表示对文本模式中指定模式第n次出现的情况进行替换 |
g | 对模式空间的所有出现的情况进行全局更改。而没有g是通常只有第一次出现的情况被取代 |
p | 打印模式空间的内容 |
w file | 将模式空间的内容写到文件file中 |
Replacement 是一个字符串,用来替换与正则表达式匹配的内容。在此部分下列字符有特殊含义:
Replacement | 含义 |
---|---|
& | 用正则表达式匹配的内容进行替换 |
\n | 匹配第n个字串(n是一个数字),这个字串出现在pattern中用“\(“和“\)”指定 |
\ | 当在替换部分包含“&”符号,反斜杠(\)和替换命令的定界符时可用\转义它们 |
2、删除
删除命令为(d)。它采用一个地址,如果行匹配这个地址,就删除模式空间的内 容
删除命令还是一个可以改变脚本中的控制流命令。这是因为一旦执行这个命令, 那么在“空的”模式空间中就不会再有命令执行。删除命令会导致读取新的输入 行,而编辑脚本则从头开始新的一轮
注意:如果某行匹配这个地址,那么就删除整个行,而不只是删除行中 匹配的部分(要删除行的一部分,可以使用替换命令并指定一个空的替换)
例如:
DcHuang@linux-fh38:~> cat 1.txt
11 22 33 44
11 22 11 44
aa bb cc dd
bb cc dd ee
## 删除包含 bb 的行
DcHuang@linux-fh38:~> sed '/bb/d' 1.txt
11 22 33 44
55 66 77 88
11 22 11 44
3、追加、插入和更改
追加(a)、插入(i)和更改(c) 命令提供了通常在交互编辑(vi)中所选择的编 辑功能。你会惊奇的发型、可以使用这些相同的命令在非交互编辑器中 “输入”文本。(必须在多行上来指定)语法如下:
追加 [line-address]a\ text
插入 [line-address]i\ text
更改 [address]c\ text
a、追加命令将文本放置在当前行之后
i、插入命令将所提供的文本放置在模式空间的当前行之前。
c、更改命令用所提供的文本取代模式空间的内容。
注意:这些命令中每个都要求后面跟一个反斜杠用于转义第一个行尾。 text必须从下一行开始。要输入多行文本,每个连续的行必须用反斜杠 结束,最后一行例外
4、列表
列表命令(l) 用于显示模式空间的内容,将非打印的字符显示为两个数字 的ASCII代码。其功能类似于vi中的列表命令(:l)。可以用改命令来检查输 入中的“不可见”字符
5、转换
转换命令式特有的,这个命令按位置将字符串abc中的每一个字符,都转 换成字符xyz中的等价字符。语法如下:
[address]y/abc/xyz/
替换根据字符的位置来进行。因此,他没有“词”的概念
6、打印、打印行号
打印命令(p) 输出模式空间的内容。除非抑制(-n)默认的输出,否则打 印命令将输出行的重复内容。
打印行号:跟在地址后面的等号(=)打印被匹配的行的行号除非抑制行的 自动输出,行号和行本身将被打印。语法如下:
[line-address]=
7、下一步
下一步(next)命令(n)输出模式空间的内容,然后读取输入的下一行,而 不用回到脚本顶端。它的语法如下:
[address]n next
命令改变了正常的流控制,直到到达脚本底部才会输出模式空间的 内容,它总是在输入新行之后从脚本的顶端开始。next命令导致输入的 下一行取代横穿空间中的当前行,脚本中的后续命令应用于替换后的行, 而不是当前行(看看例子)
## 文件1.txt
[DcHuang@local167 ~]$ cat 1.txt
11111111
abcdefgh
abcdefgh
44444444
55555555
abcdefgh
## 匹配 abc 关键字,将abc 替换为 Huangdc
[DcHuang@local167 ~]$ sed '/abc/{s/abc/Huangdc /}' 1.txt
11111111
Huangdc defgh
Huangdc defgh
44444444
55555555
Huangdc defgh
<strong>## 匹配 abc 关键字,将匹配行的下一行的 abc 替换为 Huangdc</strong>
[DcHuang@local167 ~]$ sed '/abc/{n;s/abc/Huangdc /}' 1.txt
11111111
abcdefgh
Huangdc defgh
44444444
55555555
abcdefgh
8、读和写文件、退出
读(r)和写(w)命令用于直接处理文件。这两个命令都只有一个参数,及 文件名。语法如下:
[line-address]r file [address]w file
退出命令(q)会使sed停止读取新的输入行(并停止将他们发送到输出)。它 只适用于单行地址,语法如下:
[line-address]q
## 简单看看文件 1.txt 的内容
[DcHuang@local167 ~]$ cat 1.txt
11111111
abcdefgh
abcdefgh
44444444
55555555
abcdefgh
## 匹配文件1.txt 的包含abc的行 写入文件 2.txt
[DcHuang@local167 ~]$ sed '/abc/w 2.txt' 1.txt
11111111
abcdefgh
abcdefgh
44444444
55555555
abcdefgh
[DcHuang@local167 ~]$ cat 2.txt
abcdefgh
abcdefgh
abcdefgh
## 匹配文件1.txt ,在包含 444 的行下读入文件2.txt 的内容
[DcHuang@local167 ~]$ sed -i '/444/r 2.txt' 1.txt
[DcHuang@local167 ~]$ cat 1.txt
11111111
abcdefgh
abcdefgh
44444444
abcdefgh
abcdefgh
abcdefgh
55555555
abcdefgh
## 针对文件 1.txt ,将匹配行“444”下一行的abc替换成Huangdc
[DcHuang@local167 ~]$ sed '/444/{n;s/abc/Huangdc /}' 1.txt
11111111
abcdefgh
abcdefgh
44444444
Huangdc defgh
abcdefgh
abcdefgh
55555555
abcdefgh
## 如果加上退出 q 命令,sed将直接退出
[DcHuang@local167 ~]$ sed '/444/{n;s/abc/Huangdc /;q}' 1.txt
11111111
abcdefgh
abcdefgh
44444444
Huangdc defgh
好了,sed 的基础命令我们先说到这里 , 哈哈