大数据兼云计算(王明龙)讲师-LINUX-DAY11-SED

**

Sed命令

**
sed是一个很好的文件处理工具,本身是一个管道命令,主要是以行为单位进行处理,可以将数据行进行替换、删除、新增、选取等特定工作,下面先了解一下sed的用法

s临时替换文件内容(不会改变原文件)

替换行内容

1.替换所有行

sed ‘s/原内容/新内容/’ filename //后面必须要跟/,要不不管用

sed ‘s/原内容/新内容/g’ filename

2.替换某一行

sed ‘行数s/原内容/新内容/’ 文件名

例 # sed ‘1s/原内容/新内容 filename

替换列内容

sed ‘s/原内容/新内容/列数’ 文件名

例 # sed ‘s/原内容/新空容/1’ filename

sed -r ‘s/原字符+/新字符/’文件名 // -r代表支持扩展原字符,+代表前置字符0个或多个

多重替换
1.加;号方式

sed ‘s/原内容/新内容/;s/原内容/新内容/’ filename //多加了;号,想替换列多可以加更多;

2.加-e参数方式

sed ‘s/原内容/新内容/’ -e ‘s/原内容/新内容/’ filename

-f调用脚本方式替换

vim b.sh

 s/原内容/新内容/

sed -f b.sh filename

或>> 永久替换文件内容

sed’s/原内容/新内容/’filename > filename.bak //注意filename文件是新内容,

                                          filename.bak才是原文件的一个备份

-n禁止替换的文件内容在屏幕显示

sed -n ‘s/原内容/新内容/’ filename

基本元字符:
. 匹配除换行符之外的任意单个字符,awk中可以匹配换行符
例 # sed ‘4s/./w/’ a.txt
* 匹配任意一个(包括零个)在它前面的字符
.* 匹配0个或多个任意字符
[…] 匹配方括号中的任意一个字符,^为取不匹配或称取反, -表示字符的范围
例 # sed ‘s/[a-z]/w/’ a.txt
# sed ‘s/[^a-z]/w/’ a.txt
^ 作为正则表达式的第一个字符,匹配行的开始。在awk中可以嵌入换行符
例 # sed ‘s/^/wang/’ a.txt
作为正则表达式的最后一个字符,匹配行的结尾。在awk中可以嵌入换行符             例  # sed ‘s/ /wang/’ a.txt
{n,m} 匹配前置字符出现n和m之间的任意次数
例 # sed ‘s/i{5,6}/wang/’ a.txt
{n} 匹配出现n次
例 # sed ‘s/i{5}/wang/’ a.txt
{n,}匹配至少出现n次
例 # sed ‘s/i{1,}/wang/’ a.txt
\ 转义字符
例 # sed ‘s/./wang/’ a.txt
//这个.本来代表任意一个字符,现在就代表自已本身
; 多重替换
例 # sed ‘s/r/wang/;s/d/ming/’ a.txt

扩展元字符
Extended Metacharacters (egrep and awk)

使用-r支持扩展元字符,否则无效

sed -r

  • 匹配前面的正则表达式的出现一次或多次出现
    例 # sed -r ‘s/i+/wang/’ a.txt
    ? 匹配前面的正则表达式的出现零次或一次出现
    例 # sed -r ‘s/r?/wang/’ a.txt
    | 可以匹配前面的或后面的正则表达式(替代方案)
    例 # sed -r ‘s/t|i/wang/’ a.txt
    () 对正则表达式分组
    例 # sed ‘s/(ro)(o)/wang/’ a.txt 或 # sed -r ‘s/(ro)(o)/wang/’ a.txt
    将roo为分两组,然后替换。
    {n,m} 匹配前置字符出现的n到m次数
    例 # sed -r ‘s/i{1,5}/wml/’ a.txt
    {n}匹配前置字符出现n次
    例 # sed -r ‘s/i{5}/wml/’ a.txt
    {n,}匹配前置字符至少出现n次
    例 # sed -r ‘s/i{5,}/wml/’ a.txt
    ^ 代表以什么开头
    例 # sed ‘s/^/#/’ 文件名 //给所有行加注释
    # sed ‘s/^a/#/’ 文件名 //给以a开头的字符加上#
    代表以什么结尾          例 # sed ‘s/a /b/’ 文件名 //给所有以a结尾的字符全部替换成b
    # sed ‘s/^$/b/’ 文件名 //给所有空行替换成b
    [abc] 中括号代表或者 ,或者a,或者b,或者c
    [a-z] 中括号内-代表a到z中其中一个
    例 # sed ‘s/[a-z][-+*/]/A/’ 文件名
    [a-zA-Z]
    [^abc] 取反
    大多数awk都不支持,用于POSIX egrep和POSIX awk

模式匹配产生的结果术语:
Hits(命中)
这是我想匹配的行

Misses(未命中)
这是我不想匹配的行

Omissions(遗漏)
这是我不能匹配但想要匹配的行

False alarms(假警报)
这是我不想匹配的但却匹配了的行

正则表达式分类应用:
[] 中括号内代表或者
字符类
[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] //代表不匹配0到9之间任意1个字符
[^a-z] //代表不匹配a到z之间任意1个字符
………

重复出现的字符
10
50
100
500
1000
5000
[15]0*
[15]00*

字符的跨度
* 与 {n,m}
电话号码的匹配
[0-9]{3}-[0-9]{7,8}

分组操作
compan(y|ies)
注意:大多数sed 和grep 不能对圆括号()进行匹配,但是在egrep 和
awk 所有版本都是可以的

基本的sed 命令
语法:
sed [options] ‘command’ filename
选项 指令

options 部分:

-n 不打印替换后的文件内容在屏幕显示
例 # sed -n ‘s/i{5}/wang/’ a.txt
-e 给予sed多个命令匹配多值的时候需要-e或;选项
例 # sed -e ‘s/root/haha/g’ -e ‘s/bash/wwwww/g’ passwd > passwd.bak
如果不用-e选项也可以用分号“;”把多个命令隔开。
例 # sed’s/haha/ro/g ; s/wwwww/kkkk/g’ passwd | less

-i -i后没有扩展名的话直接修改文件,如有扩展名备份源文件,产生以扩展名结尾新文件
注意:选项-i后面没有空格
例 # sed -ibak -e ‘s/root/rottt/g’ -e ‘s/bash/wwwww/g’ filename
(bak为原文件名后加的后缀) (filename为原文件名)
[root@localhost 桌面]# ls
manifest.txt filename.bak
-f 当有多个要编辑的项目时,可以将编辑命令放进一个脚本里,再使用sed搭配-f选项
[root@localhost 桌面]# cat wml.sh
s/bin/a/g
s/ftp/b/g
s/mail/c/g
[root@localhost 桌面]# sed -f wml.sh filename | less

sed命令和选项
a\ 在当前行后添加一行或多行
c\ 用新文本替换当前行中的文本
d 删除行
i\ 在当前行之前插入文本
h 把模式空间的内容复制到暂存缓冲区
H 把模式空间的内容添加到缓冲区
g 取出暂存缓冲区的内容,将其复制到模式缓冲区
G 取出暂存缓冲区的内容,将其追加到模式缓冲区
l 列出非打印字符
p 打印行
n 读入下一行输入,并从下一条而不是第一条命令对其处理
q 结束或退出sed
r 从文件中读取输入行
! 对所选行以外的行应用所有命令
s 用一个字符串替换另外一个字符串

替换标志:
g 在行内进行全局替换
p 打印行
w 将行写入文件
x 交换暂存缓冲区和模式空间的内容
y 将字符转换成另外一个字符

举例

打印:p命令
sed ‘/abc/p’ file 打印file中包含abc的行。默认情况sed把所有行都打印到屏幕,如果某行匹配到模式,则把该行另外再打印一遍
sed -n ‘/abc/p’ file 和上面一样,只是去掉了sed的默认行为,只会打印匹配的行

删除:d命令
sed ‘3, d f i l e 3 s e d d’ file 删除最后一行的内容
sed ‘/abc/d’ 删除包含abc的行。
sed ‘3d’ file 删除第三行的内容

替换:s命令
sed ‘s/abc/def/g’ file 把行内的所有abc替换成def,如果没有g,则只替换行内的第一个abc
sed -n ‘s/abc/def/p’ file 只打印发生替换的那些行
sed ‘s/abc/&def/’ file 在所有的abc后面添加def(&表示匹配的内容)
sed -n ‘s/abc/def/gp’ file 把所有的abc替换成def,并打印发生替换的那些行
sed ‘s#abc#def#g’ file 把所有的abc替换成def,跟在替换s后面的字符就是查找串和
替换串之间的分割字符,本例中试#

指定行的范围:逗号
sed -n ‘/abc/,/def/p’ file 打印模式abc到def的行
sed -n ‘5/,/def/p’ file 打印从第五行到包含def行之间的行。
sed /abd/,/def/s/aaa/bbb/g 修改从模式abc到模式def之间的行,把aaa替换成def

多重编辑-e
sed -e ‘1,3d’ -e ‘s/abc/def/g’ file 删除1-3行,然后把其余行的abc替换成def

读文件:r命令
sed ‘/abc/r newfile’ file 在包含abc的行后读入newfile的内容

写文件:w命令
sed ‘/abc/w newfile’ file 在包含abc的行写入newfile

追加:a命令
sed ‘/abc/a\def’ file 在包含abc的行后新起一行,写入def

插入:i命令
sed ‘/abc/i\def’ file 在包含abc的行前新起一行,写入def

修改:c命令

sed ‘/abc/c\def’ file 在包含abc的行替换成def,旧文本被覆盖

读取下一行:n命令
sed ‘/abc/{n ; s/aaa/bbb/g;}’ file 读取包含abc的行的下一行,替换aaa为bbb

转换:y命令
sed ‘y/abc/ABC/’ file 将a替换成A,b替换成B,c替换成C(正则表达式元字符不起作用)

退出:q命令
sed ‘/abc/{ s/aaa/bbb/ ;q; }’ file 在某行包含了abc,把aaa替换成bbb,然后退出sed。

暂存和取用:h命令(把模式行存储到暂存缓冲区)和g(取出暂存缓冲区的行并覆盖模式缓冲区)G(取出临时缓冲区的行)命令
h和g是复制行为(覆盖),H和G表示追加。
sed -e ‘/abc/h’ -e ‘ G f i l e a b c h s e d 时,G命令从暂存缓冲区中读取一行,追加到模式缓冲区的后面。即所有包含abc的行的最后一行被复制到文件末尾。
sed -e ‘/abc/{h; d;}’ -e ‘/def/{g; }’ file 包含abc的行会移到包含def的行上,并进行覆盖。

暂存和互换:h和x命令
sed -e ‘/abc/h’ -e ‘/def/x’ file 包含abc的行会被换成def的行。

S 替换的基本语法
语法 # sed 参数 定址(要匹配的行数或字符)s/原内容/替换后的内容/要匹配的例数
1.匹配行数和例数的语法
# sed’行数/s/原内容/新内容/列数’ filename
例 # sed ‘10/s/root/wang/3’ file.txt
2.匹配字符或字符串的语法
# sed ‘/字符或字符串/s/原内容/新内容/’ filename
例 # sed ‘/root/s/w/I/’ a.txt

P 打印文件内容,会给要匹配文件内容在多打出一行来
语法 # sed ‘/匹配的内容/p’ filename
例 # cat a.txt
rootwml
aaaaaa
# sed ‘/root/p’ a.txt
rootwml
rootwml
aaaaaa
w 将匹配行写入文件并覆盖
3.语法 # sed ‘s/原内容/新内容/ 文件名’
例 # cat a.txt
rootwml
Aaaaaa
bbbbbb
# sed ‘s/root/ROOT/w a.txt’
ROOTwml
= 打印行号
语法 # sed ‘=’filename 打印所有行的行号
# sed ‘行号=’ filename 打印指定行的行号
1.打印所有行的行号
例 # sed ‘=’ a.txt
1
rootiiiiii
2
aaaaaa
3
bbbbbb
4
cccccc
例 # sed ‘2=’ a.txt
rootiiiiii
2
aaaaaa
bbbbbb
cccccc

添加,插入,修改行内容
a 添加一行内容
语法 # sed ‘行数a 要添加的内容’filename
例 # sed’3a wml’a.txt 在第3行添加wml的内容
i 插入一行内容
语法 # sed ‘行数i 要插入的内容’filename
例 # sed’2i wang’a.txt 在第2行插入wang的内容
c 修改一行内容
语法 # sed’行数c 要修改成的内容’filename
例 # sed’2c ming’a.txt 把第2行修改成ming的内容
d 删除内容
语法 # sed’行数d’ filename
例 # sed ‘4,10d’ a.txt 删除4到10行内容
# sed ‘4d’ a.txt 删除4行内容
什么是定址:要匹配文件内容的位置和字符
command 部分:
‘[地址1,地址2] [函数] [参数(标记)]’
定址:
行地址对于任何命令都是可选的,它可以是一个模式,或者由斜杠、行号或行寻址符号括住的正则表达式, 大多数sed命令能接受由逗号分隔的两个地址,有些命令只接受单个行地址
命令还可以用大括号进行分组,第一个命令可以和大括号放在同一行,
但是右大括号必须自己一行

定址的方法 1.数字 2.正则
数字(行号):
十进制数
1单行

sed -n ‘1p’ passwd p是打印函数

     1,3    范围 从第一行到第三行      

sed -n ‘1,3p’ passwd

     2,+4   匹配行后若干行         
     4,~3  从第四行到下一个3的倍数行
     1~3   第一行起每间隔三行的行
     $ 尾行
     1! 除了第一行以外的行
正则:
   正则必须用//包裹起来
   扩展正则需要用 -r 参数或转移

范例:

cat file.txt

.TS
Beijing,CN
.TE
Shanghai,CN
guangzhou,CN
shenyang,CN

sed ‘/Beijing/s/CN/China/’ file.txt

删除所有的行
d
只删除第一行
1d
使用寻址符号 d
删除空行,正则表达式必须封闭在斜杠//当中
/^ / d . T S . T E t b l / . T S / , / . T E / d 5 , d
混合使用行地址和模式地址

sed ‘1,/^$/d’ file.txt

删除除了那些行以外的行

1,5!d

分组命令
/^.TS/,/^.TE/{
s/CN/China/
s/Beijing/BJ/
}

sed ‘2,3s{/cn/china/;s/a/b/}’ file.txt 同一范围的两个替换可以用大括号括起来一起,中间加分号

函数:
增删改:
a 后插
c 替换
i 前插

  d 删除

删除模式空间的内容,同时改变脚本的控制流,执行这个命令后,在“空
的”模式空间不再有命令执行。删除命令会导致读取新的输入行

替换:[address ]s/pattern /replacement /flags
标志flags是:
n 可以是1-512,表示第n次出现的情况进行替换
g 全局更改
p 打印模式空间的内容
w file 写入到一个文件file中

  s 字符串替换 s/old/new/
 替换的时候可以把/换成其他的符号,比如=   
  #sed -n 's/root/ABCDEF/p' /etc/passwd
  ABCDEF:x:0:0:root:/root:/bin/bash
  operator:x:11:0:operator:/ABCDEF:/sbin/nologin

  #sed -n 's/root/ABCDEF/2p' /etc/passwd
  root:x:0:0:ABCDEF:/root:/bin/bash

  #sed -n 's/root/ABCDEF/3p' /etc/passwd
  root:x:0:0:root:/ABCDEF:/bin/bash

  #sed -n 's/root/ABCDEF/gp' /etc/passwd
  ABCDEF:x:0:0:ABCDEF:/ABCDEF:/bin/bash
  operator:x:11:0:operator:/ABCDEF:/sbin/nologin

replacement部分用下列字符会有特殊含义:
& 用正则表达式匹配的内容进行替换
\n 回调参数
()保存被匹配的字符以备反向引用\N时使用,最多9个标签 标签顺序从左至右

cat test1

first:second
one:two

sed ‘s/(.):(.)/\2:\1/’ test1

second:first
two:one
试做:
删除第一个单词
删除最后一个单词
将第一个单词和最后一个单词兑换位置

y 字符替换(变形)
r 从文件中读入内容到指定行的后面

#sed’2r b.txt’ a.txt 将b.txt文件内容读入到文件b.txt的第2行后面

工作模式:模式空间和保持空间介绍
模式空间初始化为空,处理完一行后会自动输出到屏幕并清除模式空间。
保持空间初始化为一个空行,也就是默认带一个\n,处理完后不会自动清除

sed -e ‘s/pig/cow/’ -e ‘s/cow/horse/’

sed ‘1{p;p}’ a.txt

11111111
11111111
11111111
22222222
33333333
44444444
55555555
66666666

置换 模式空间和保持空间(暂存空间)
  h 把模式空间内容覆盖到保持空间中
  H 把模式空间内容追加到保持空间中
  g 把保持空间内容覆盖到模式空间中
  G 把保持空间内容追加到模式空间中
  x 交换模式空间与保持空间的内容

# cat test.sh 
1111111
2222222 
3333333
4444444
# sed  '{1h;2,3H;4G}'  ./test.sh 
1111111
2222222
3333333
4444444
1111111
2222222
3333333
# sed  '{1h;2x;3g;$G}'  ./test.sh 
1111111
1111111
2222222
4444444
2222222

反转:
/1/{
h
d
}
/2/{
G
}

控制流
! 命令取反 例: 1!d 删除第一行以外的行
{} 命令组合 命令用分号分隔 {1h;G} 可以理解为 -e 参数的另一种写法
= 打印行号(输入行的号码,而非处理的次数行号) 例如: sed -n ‘2{=;p}’ infile
n 读入下一行到模式空间 例:’4{n;d}’ 删除第5行
N 而是追加下一行到模式空间,再把当前行和下一行同时应用后面的命令
P 输出多行模式空间的第一部分,直到第一个嵌入的换行符为止。在执行完脚本的最后一个命令之后,模式空间的内容自动输出。
P命令经常出现在N命令之后和D命令之前。
D 删除模式空间中直到第一个换行符的内容。它不会导致读入新的输入行,相反,它返回到脚本的顶端,将这些指令应用与模式空间剩余的内容。
这三个命令能建立一个输入、输出循环,用来维护两行模式空间,但是一次只输出一行。
这个循环的目的是只输出模式空间的第一行,然后返回到脚本的顶端将所有的命令应用于模式空间的第二行。没有这个循环,当执行脚本中的最后一个命令时,模式空间中的这两行都将被输出。

   删除文件倒数第二行
   sed 'N;$!P;D' a.txt
   删除文件最后两行
   sed 'N;$!P;$!D;$d' a.txt

试做题
将第一行插入到每个偶数行的后面

s e d 1 h ; 0   2 G a . t x t 11111111 22222222 11111111 33333333 44444444 11111111 55555555 66666666 11111111
颠倒输出
s e d 1 ! G ; h ; !d’ rev.txt
xyz
def
abc
$

大写转换
样本文件 a.txt
find the Match statement
Consult the Get statement.
using the Read statement to retrieve data
将 the 和statement之间的单词转换成大写
脚本:changsrc

capitalize statement names

/the .* statement/{
h
s/.the (.) statement.*/\1/
y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
G
s/(.)\n(.*the ).( statement.*)/\2\1\3/
}

脚本方法
-f 参数 引用脚本(脚本的末尾不能有空格制表符或其他文本)
# cat sed.sh
2,4d
s/777/seker/
s/999/seker&seker/
# sed -f sed.sh test.txt
1111111
5555555
6666666
seker7777
8888888
seker999seker9999
#

在脚本中指明解释器为sed
# cat sed.sh
#!/bin/sed -f
2,4d
s/777/seker/
s/999/seker&seker/
# ./sed.sh test.txt
1111111
5555555
6666666
seker7777
8888888
seker999seker9999
#

高级流控命令 b分支 t测试
分支命令用于无条件转移,测试命令用于有条件转移

分支 branch
跳转的位置与标签相关联
如果有标签则跳转到标签所在的后面行继续执行
如果没有标签则跳转到脚本的结尾处.
标签 以冒号开始后接标签名 不要在标签名前后使用空格
跳转到标签指定位置
[root@stu254 ~]# grep seker /etc/passwd
seker:x:500:500::/home/seker:/bin/bash
[root@stu254 ~]#
[root@stu254 ~]# grep seker /etc/passwd |sed ‘:top;s/seker/blues/;/seker/b top;s/5/555/’
blues:x:55500:500::/home/blues:/bin/bash
[root@stu254 ~]#

命令分析:让单次替换(cmd1)循环执行,直到条件不满足
:top; 定义一个top标签
s/seker/blues/; cmd1
/seker/b top; 如果模式匹配则跳转到top标签
s/5/555/ 当上一条模式不匹配时,既会继续执行这一条

选择执行
[root@stu254 ~]# grep ‘seker’ /etc/passwd |sed ‘s/seker/blues/;/seker/b end;s/5/555/;:end;s/5/666/’
blues:x:66600:500::/home/seker:/bin/bash
[root@stu254 ~]#

zorro:x:501:501::/home/zorro:/bin/bash
[root@stu254 ~]# grep ‘zorro’ /etc/passwd |sed ‘s/seker/blues/;/seker/b end;s/5/555/;:end;s/5/666/’
zorro:x:6665501:501::/home/zorro:/bin/bash
[root@stu254 ~]#

命令分析: 执行cmd1,再去模式匹配,成功则跳转到cmd3开始执行,否则(模式不匹配)会按命令顺序逐个执行
s/seker/blues/; cmd1
/seker/b end;
s/5/555/; cmd2
:end;
s/5/666/ cmd3

另一种选择执行
[root@stu254 ~]# grep ‘seker’ /etc/passwd |sed ‘s/seker/blues/;/seker/b end;s/5/555/;b;:end;s/5/666/’
blues:x:66600:500::/home/seker:/bin/bash

[root@stu254 ~]# grep ‘zorro’ /etc/passwd |sed ‘s/seker/blues/;/seker/b end;s/5/555/;b;:end;s/5/666/’
zorro:x:55501:501::/home/zorro:/bin/bash
[root@stu254 ~]#

命令分析: 执行cmd1;模式匹配cmd2成功则执行cmd3;否则执行cmd2,再跳转到脚本末尾
s/seker/blues/; cmd1
/seker/b end;
s/5/555/; cmd2
b;
:end;
s/5/666/ cmd3

测试命令,如果前一个替换命令执行成功则跳转到脚本末尾 (case结构)
[root@stu254 ~]# grep ‘seker’ /etc/passwd |sed ‘s/seker/ABC/;t;s/home/DEF/;t;s/bash/XYZ/’
ABC:x:500:500::/home/seker:/bin/bash

[root@stu254 ~]# grep ‘zorro’ /etc/passwd |sed ‘s/seker/ABC/;t;s/home/DEF/;t;s/bash/XYZ/’
zorro:x:501:501::/DEF/zorro:/bin/bash
[root@stu254 ~]#

与标签关联,跳转到标签位置
[root@stu254 ~]# grep ‘seker’ /etc/passwd |sed ‘s/seker/ABC/;t end;s/home/DEF/;t;:end;s/bash/XYZ/’
ABC:x:500:500::/home/seker:/bin/XYZ

sed -r 支持扩展正则

sed -n 屏蔽默认输出,也中静默输出

sed -i

sed -f 把脚本写进文件

sed命令替换文件文件内容

sed在Linux下是个强大的工具,这里主要说替换:

1、替换并输出(不修改源文件):

sed ‘s/dog/cat/g’ file ##dog被替换的内容,cat替换的内容

2、备份后直接替换至源文件:

sed -i.bak ‘s/dog/cat/g’ file

3、替换第n行到第m行:

sed ‘n,ms/dog/cat/g’ file ##n、m为数字

4、替换内容xxx和*之间的内容:

sed ‘/A/,/B/s/dog/cat/g’ file ##替换A和B之间的内容

5、一次替换多个多个内容:

sed -e ‘s/dog1/cat1/g’ -e ‘s/dog2/cat2/g’ file

猜你喜欢

转载自blog.csdn.net/wangminglong1989/article/details/81386866