语法:
sed [options] 'command' in_file[s]
options 部分:
-n 静默输出(不打印默认输出)
-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后面没有扩展名的话直接修改文件,如果有扩展名备份源文件,产生以扩展名结尾的新文件
sed -iback1 -e 's/root/rottt/g' -e 's/bash/wwwww/g' passwd.back //选项-i后面没有空格
[root@localhost 桌面]# ls
manifest.txt passwdback1
-f 当有多个要编辑的项目时,可以将编辑命令放进一个脚本里,再使用sed搭配-f选项
[root@localhost 桌面]# cat s.sed
s/bin/a/g
s/ftp/b/g
s/mail/c/g
[root@localhost 桌面]# sed -f s.sed passwd | less
command 部分:
‘[地址1,地址2] [函数] [参数(标记)]'
定址: /[0-9]+/ 以它为 地址标准的才能执行后边awk内容或sed内容
行地址对于任何命令都是可选的,它可以是一个模式,或者由斜杠、行号或行寻址符号括住的正则表达式, 大多数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
删除.TS 和.TE 标记的tbl 输入
/.TS/,/.TE/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中
i 忽略大小写
[root@wing ~]# echo Aaaaba | sed -r 's/a.*/B/'
AB
[root@wing ~]# echo Aaaaba | sed -r 's/a.*/B/i'
B
s 字符串替换 s/old/new/
替换的时候可以把/换成其他的符号,比如=
#sed -n 's/root/ABCDEF/p' /etc/passwd
ABCDEF:x:0:0:root:/root:/bin/bash
replacement部分用下列字符会有特殊含义:
& 用正则表达式匹配的内容进行替换
\n 回调参数
\(\)保存被匹配的字符以备反向引用\N时使用,最多9个标签 标签顺序从左至右
#cat test1
first:second
one:two
#sed ‘s/\(.*\):\(.*\)/\2:\1/' test1
second:first
two:one
y 字符替换(变形) y是替换整个字符串 s也可以但是s是一个一个匹配的
r 从文件中读入内容到指定行的后面
#sed‘2r b.txt’ a.txt 将b.txt文件内容读入到文件a.txt的第2行后面
=====================================================================
工作模式:模式空间和保持空间介绍
模式空间:初始化为空,处理完一行后会自动输出到屏幕并清除模式空间。
: 将符合内容进行更改 将更改的内容作为下一个的要更改的内容
: 将第一行处理完后 将处理过的内容 打印出来,将模式空间清楚 换第二行来处理
置换:模式空间和保持空间(暂存空间)
h 把模式空间内容覆盖到保持空间中
H 把模式空间内容追加到保持空间中
g 把保持空间内容覆盖到模式空间中
G 把保持空间内容追加到模式空间中
x 交换模式空间与保持空间的内容
d删除模式空间的所有内容,并接着读入下一行到模式空间
颠倒输出 直接用tac 就可以颠倒
$ sed '1!G;h;$!d' rev.txt
xyz
def
abc
$
详解
1!G;h;$!d
文本
1
2
3
模式空间 保持空间
第一行 1 1 后边将覆盖
第二行 2 2 后边将覆盖
1 1
第三行 3 3
2 2
1 1
cat passwd |tac
:wq
1
1
1
1
1
o
xiaomi:x:1000:1000:xiaomi:/home/xiaomi:/bin/bash
tcpdump:x:72:72::/:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
emon:x:2:2:daemon:/sbin:/sbin/nologin
# 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
保持空间:相当于粘贴板 里边内容不会主动被清空
保持空间:初始化为一个空行,也就是默认带一个\n,处理完后不会自动清除。
控制流
! 命令取反 例: 1!d 删除第一行以外的行
{} 命令组合 命令用分号分隔 {1h;G} 可以理解为 -e 参数的另一种写法
= 打印行号(输入行的号码,而非处理的次数行号) 例如: sed -n '2{=;p}' infile
n 读入下一行到模式空间 例:'4{n;d}' 删除第5行
N 而是追加下一行到模式空间,再把当前行和下一行同时应用后面的命令
P 输出多行模式空间的第一部分,直到第一个嵌入的换行符为止。在执行完脚本的最后一个命令之后,模式空间的内容自动输出。
P命令经常出现在N命令之后和D命令之前。
D 删除模式空间中直到第一个换行符的内容。它不会导致读入新的输入行,相反,它返回到脚本的顶端,将这些指令应用与模式空间剩余的内容。
这三个命令能建立一个输入、输出循环,用来维护两行模式空间,但是一次只输出一行。
这个循环的目的是只输出模式空间的第一行,然后返回到脚本的顶端将所有的命令应用于模式空间的第二行。没有这个循环,当执行脚本中的最后一个命令时,模式空间中的这两行都将被输出。
# tac 将文本内容倒过来
# cat a.txt |tac
删除文件倒数第二行
#sed 'N;$!P;D' a.txt
N将下一行追加到模式空间中 现在模式空间中会有 第一行和第二行
交给P来进行 P将 第一行输出 出来
交给D来进行 D将 第一行删除 然后重新执行子命令 然后在来一边
这样循环如果只有N;P;D 内容将不会该变什么 因为他可以循环到底
在p前边加$! 是为了取反 执行最后一行之外的行 N将最后一行和倒数第二行放里边了
P执行时 不执行最后一行直接略过交给D执行 然后他把第一行删除掉 内容中的第二行就被删除了
然后再循环一次 因为后边没有内容了 N不再执行 P将第一行输出 粘贴板没有内容了 D也不执行
删除文件最后两行
sed 'N;$!P;$!D;$d' a.txt
练习:
将第一行插入到每个偶数行的后面
$ sed '1h;0~2G' a.txt
11111111
22222222
11111111
33333333
44444444
11111111
55555555
66666666
11111111
脚本方法
-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/