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 删除(以行为单位)
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