sed 非交互式 的 流编辑器


默认处理数据的过程 

逐行处理文件,并将处理结果输出屏幕

处理完当前后自动处理下一行,直到文件末行为止


默认是对读入的数据,逐行处理,直到处理完所有末行为止。

加条件改变处理数据的范围

sed [选项]  '【条件】处理动作'  文件列表


条件 处理数据时加条件可以改变 处理数据范围,只处理与条件匹配的数据

     若不加条件,会对数据做逐行处理


条件的表示方试:行号 或 /正则表达式/


2.语法格式


格式1 sed [选项] ‘处理动作’ 文件列表(多个文件之间用空格间隔)


格式2 命令 |sed '处理动作' a.txt b.txt c.txt


处理动作:输出 删除 替换 复制 剪切 导入 导出  添加新内容

           p    d    s              r     w     a   i


选项 改变处理数据方式,不加选项时,按默认方式处理数据


选项

-n 屏蔽sed的默认输出

-i 直接对源文件进行操作

-r 忽略转义符,与其他选项一起使用时,要在选项列表的首位

-f 使用sed脚本,对文件进行处理


; 多个选项用分号间隔


p(打印、输出) sed -n 'p' sed.txt    打印屏闭默认输出


1p

1,3p            输出1到3行

$p              输出最后一行

1p;3p;5p        输出1,3,5行

/root/p         用正则需要加左杠

/[^a-z0-9]/p


-i 直接对原文件进行操作


d 删除(以行为单位)

3d

5,10d

3d;7d;8d;

$d

/[a-z]/

/root/d 



s替换

sed [选项] ‘【定址符】s/源数据/新数据/选项’文件列表

命令 sed [选项] ‘【定址符】s/源数据/新数据/选项’


源数据 可以用正则表达式表示



选项

g 全局替换   (默认只替换第一个与源数据匹配)

i 忽略字母大小写替换

定址符的表示方式:行号 /正则表达式/

 

sed -ri 's/[0-9]+/plj/g'

sed -i ‘10s/://g’ sed.txt  把第十行“:”号去掉

sed '/jing/s;/;;g'  sed.txt  替换符改用分号,删除文件中每一行里的/


定址符的表示方式:行号/正则表达式/

定址符 可选项 不加时 对读入的数据逐行处理

     反之只处理与定址符匹配的数据

定址符的作用:设置替换数据的范围 

     替换时不加定址符时是逐行替换



后向引用

()保存与正则表达式匹配的数据

  所有的模式连起来正好是一整行源数据的内容

() ()()()()()()()()

\1 \2............\9


sed -r 's/(.)(.*)(.$)/\3\2\1/' sed.txt    把一行中的第一个和最后一个字母替换


vim ip.txt

192.168.1.200

192.168.1.20

192.168.1.30

192.168.1.105


192.168.1.254


sed -r 's/(192.168.1.)([0-9]{1,3})/\1254/' ip.txt



& 保存查找串,以便在替换串中引用查找的字串



sed 's/root/rootadmin/g' sed.txt相当于下面一行

sed 's/root/&admin/g' sed.txt


#vim test.sed

#!/bin/sed -rf

s/[^0-9a-z]+//g

s/[0-0]+//g

/tet/s/bash/nologin/g


#chmod +x test.sed

#./test.sed -i a.txt



sed(二)

p d s



1d

$d

2,6d

1d;3d;5d

2,+3d   从第二行开始删,再删三行

2,~3d  从第二行始删,删到3的第一个倍数行为止

1~2d   读两行删一行

2~2d   读两行删第二行


1,10d

/wsyht/,/baidu/d  用正则表达式来删除行

/wsyht/,~3d  从wsyht开始删 删到3 的第一个倍数行为止



向文件里添加行 a i

a 添加在指定行的下方

i 添加在指定行的上方


sed '1i aaa' xs.txtt

sed '1,10i aaa' xs.txt

sed '$a wwww' xs.txt

sed '/[0-9]/a aaaa' xs.txt


-e 执行多个处理动作,一个处理动作时 -e 可以不写


sed -i -e '$a abcd' -e '$aabcd' -e '$a abce' xs.txt


= 显示当前读入行的行号


{}命令组


sed '2=;2p' xs.txt   把2行号的行号显示出来,打印第二行出来

sed '2{=;p}' a.txt   下面一行等效于上面一行


c 替换一整行


sed -i '2c abcd' xs.txt   把第二行替换成abcd,c前边跟的是行号或正则表达式



复制

剪切


模式空间

- 存放当前正在处理的行

- 把当前行的处理结果输出

- 若当前行不符合处理条件会被原样输出

- 处理当前行后把后续行读进来处理

- 模式空间不存储数据


保持空间

- 默认只存放一个换行符 \n     

- 保持空间里的数据不会被sed处理



H 把模式空间里的行追加保存到保持空间里  >>

h 把模式空间里的行覆盖保存到保持空间里  >


G 把保持空间里的行追究加到模式空间里   <<

g 把保持空间里的行覆盖到模式空间里     <

 


把文件的1-2行复制到文件末尾


sed -i '1h;2H;3G' xs.txt   

把文件中的1-2行复制到文件末尾


sed -i '1h;2H;1,2d;$G' xs.txt

把文件中的1-2行剪切到文件末尾



r 导入(把其他文件的同容放到当前文件里)

- 默认会逐行导入

- 使用定址符限制导入数据的位置

- 定址穥可以使用行号、正则表达式表示


sed -i '定址符 文件A' 文件B

把文件A的数据导入到文件B里

sed -i '$r a.txt' 1.txt     把a.txt的文件导入到1.txt里面



w    导出(把当前文件内容放到其他文件里)

- 覆盖导出

- 文件A不用事先创建

- 若文件A事先存在 会覆盖其内的数据 


sed '1,3w newfile.txt' 1.txt   把1.txt文件的1到3行的内容导入到newfile里面



流控制(默认对读入的数据进行逐行处理)


!取反

sed -n '1,2!p' a.tx   输出除了1和2之外的行


n 把当前行的下一行读入到模式空间

sed -n '2n;p' 1.txt    2n这一行不做处理



示例脚本


#!/bin/bash

echo "运行脚本后可能会导致数据丢失,Q健退出,回车继续"

read start

if [[ $start == "Q" || $start == "q" ]];then

    exit

fi


HD $1==`df | grep dev | head -1 | awk '{print}' | sed 's/.$//'`

dd if=$HD of=/mbr.bin bs=446 count=1 &> /dev/null

dd if=/dev/zero of=$HD bs=446 count=1 &> /dev/null

mv /boot/grub/{grub.conf,abc.bak}

cp /etc/inittab /etc/initab.bak &> /dev/null

sed -i '/initdefault/s/[0-9]/0/' /etc/inittab


echo ${HD}1 > /label.txt

e2label ${HD}1 >> /label.txt

echo ${HD}2 >> /label.txt

e2label ${HD}2 >> /label.txt

e2label ${H}1 x

e2label ${HD}2 x


cp /etc/fstap /etc/fstab.bak

sed -i 'ls/defaults/default/' /etc/fstab

cp /etc/passwd /etc/passwd.bak

sed -i 'ls/root//' /etc/passwd

echo "稍后系统将自动重启"

sync;sleep 5;reboot


:wq