文章目录
sed
1.1 sed概述
Sed是一个强大的文本处理工具,其名称是Stream Editor(流编辑器)的缩写。它被设计用于根据用户定义的规则对文本进行逐行处理和转换。
Sed通过从输入流中逐行读取文本,并根据用户指定的命令来按行处理。
1.2 sed原理
sed的工作原理是逐行读取输入文本,并根据用户指定的命令对每一行进行处理,通过模式匹配和命令执行来实现文本的处理和转换。
Input Text Pattern Space Output Text
------------ -------------- -------------
| Line 1 | -----> | Pattern | -----> | |
| Line 2 | | Space | | Modified |
| Line 3 | | | | Text |
| ... | | | | |
------------ -------------- -------------
1.3 sed的选项
-e:指定命令处理的文本文件,多个执行操作需要加上-e
-f:高级脚本模式
-i:修改目标文件(慎用)
-n:显示script处理之后的结果
-r:支持扩展正则表达式
1.4 操作符
- s:替换,替换指定的字符串
- g:全局(仅在替换时使用)
- d:删除选定的行
- a:新增 在指定行的下面插入一条新的内容
- i:新增 在指定行的上面插入一条新的内容
- c:整行替换为指定的内容
- y:字符替换 (转换前后的字符长度必须保持一致)
- p:打印
- r:读取文件,将其内容增加到目标文件的目标行下一行
1.5 用例
1.5.1查
sed '' 1.txt
# 打印1.txt的文本内容
sed 'p' 1.txt
# 会打印两遍,其中包括sed输出
sed -n 'p' 1.txt
# 不打印sed默认输出,只打印一遍
sed -n '=' 1.txt
# 打印行号
sed -n '=;p' 1.txt
# 打印行号和内容
sed -n '1p' 1.txt
# 打印第一行
sed -n '$p' 1.txt
# 打印最后一行
sed -n '7,$p' 1.txt
# 打印第七行到最后一行
sed -n '7p;$p' 1.txt
# 打印第七行和最后一行
sed -n 'n;p' 1.txt
# 打印偶数行(只有sed和awk能做奇偶打印)
sed -n 'p;n' 1.txt
# 打印奇数行(只有sed和awk能做奇偶打印)
sed -n '/o/p' 1.txt
# 打印所有包含o的行
正则表达式
sed -n '/^root/p' /etc/passwd
# 打印以root开头的行
sed -n '/bash$/p' /etc/passwd
# 打印以bash结尾的行
sed -n '/4,bash$/p' /etc/passwd
# 打印第4行到第一个以bash结尾的行
扩展正则表达式 -r
sed -rn '/^root|bash$/p' /etc/passwd
# 打印以root开头或以bash结尾的行
sed -rn '/(13:){2,}/p' /etc/passwd
# 打印(13:)出现至少2次的行
1.5.2 删
d
sed -i 'd' 1.txt
# 不进入文件也不删除文件,只清空文件的内容(慎用!)
cat /dev/null > 1.txt
sed '/one/,/six/d' 1.txt
# 删除包含one和six之间的所有行
sed '/one/,/six/!d' 1.txt
# 保留包含one和six之间的所有行,其余全删
sed '/^$/d' 1.txt
# 删除空行
1.5.3 改
s
格式:sed -n 's/旧字符/新字符/操作符' 文件名
sed -n 's/root/test/p' /etc/passwd
# 将每行第一个root替换成test
sed -n 's/root/test/2p' /etc/passwd
# 将每行第二个root替换成test
sed -n '/^root/ s/^/#/p' /etc/passwd
# 以root为开头的行,^表示行首没有特殊字符,#注释掉
字母的首位替换成大写
sed 's/[a-z]/\u&/' 1.txt
# \u&: u&是转换首字母大写的特殊符号,在sed使用中要\转义
sed 's/[A-Z]/\l&/' 1.txt
# \l&: l&是转换首字母小写的特殊符号,在sed使用中要\转义
字符串和字符位置的交换(重新排序)
echo test1test2 | sed -r 's/(test1)(test2)/\2\1/'
c
sed '/one/c test' 1.txt
# 将包含one的行整行替换成test
y
sed 'y/one/123/' 1.txt
# 将one字符一一对应为123替换,旧字符和新字符要保持一致
-f
sed -f 1.txt 2.txt
# 用脚本文件1.txt中的命令修改2.txt文件的内容
1.5.4 增
a
sed '/three/a 123' 1.txt
# 在包含three的行的下一行增加内容为123的行
i
sed '/three/i 123' 1.txt
# 在包含three的行的上一行增加内容为123的行
r
sed '/three/r 2.txt' 1.txt
# 读取2.txt的文本内容并将其输出到1.txt文本中three所在行的下一行
使用$a,$i,$r直接插入内容,无需匹配
$a
sed '$a 123' 1.txt
# 在文件的最后的一行的下一行插入新的内容
$i
sed '$i 123' 1.txt
# 在文件的最后的一行的上一行插入新的内容
$r
sed '$r 2.txt' 1.txt
# 读取2.txt的文本内容并将其输出到1.txt文本中最后一行的下一行
1.6 综合题:shell脚本用sed修改配置文件实现pxe自动装机
yum -y install tftp-server xinetd
sed -i 's/yes/no/' /etc/xinetd.d/tftp
echo "############### TFTP配置文件已修改完成! ###############"
systemctl restart tftp
systemctl enable tftp
systemctl restart xinetd
systemctl enable xinetd
echo "############### TFTP服务已重启! ###############"
yum -y install dhcp
cp /usr/share/doc/dhcp-4.2.5/dhcpd.conf.example /etc/dhcp/
rm -rf /etc/dhcp/dhcpd.conf
mv /etc/dhcp/dhcpd.conf.example /etc/dhcp/dhcpd.conf
sed -i -re '32s/10.254.239.0/192.168.159.0/' -e '32s/255.255.255.224/255.255.255.0/' -e '33s/10.254.239.10/192.168.159.30/' -e '33s/10.254.239.20/192.168.159.39/' -e '34s/rtr-239-0-1.example.org, rtr-239-0-2.example.org/192.168.159.12/' -e '/^#ddns/ s/#//' /etc/dhcp/dhcpd.conf
sed -i '11a next-server 192.168.159.12;' /etc/dhcp/dhcpd.conf
sed -i '12a filename "pxelinux.0";' /etc/dhcp/dhcpd.conf
echo "############### DHCP配置文件已修改完成! ###############"
systemctl restart dhcpd
systemctl enable dhcpd
echo "############### DHCP服务已重启! ###############"
mount /dev/sr0 /mnt
cd /mnt/images/pxeboot
cp vmlinuz /var/lib/tftpboot/
echo "############### Linux系统的内核文件准备完成! ###############"
cp initrd.img /var/lib/tftpboot/
echo "############### 初始化镜像文件准备完成! ###############"
yum -y install syslinux
cp /usr/share/syslinux/pxelinux.0 /var/lib/tftpboot/
echo "############### PXE引导程序准备完成! ###############"
yum -y install vsftpd
mkdir /var/ftp/centos7
echo "############### 正在复制CentOS7镜像文件 ###############"
cp -rf /mnt/* /var/ftp/centos7/
echo "############### CentOS7镜像文件复制完成! ###############"
systemctl start vsftpd
systemctl enable vsftpd
echo "############### vsftpd服务已重启! ###############"
mkdir /var/lib/tftpboot/pxelinux.cfg
echo "default auto
prompt 0
label auto
kernel vmlinuz
append initrd=initrd.img method=ftp://192.168.159.12/centos7 ks=ftp://192.168.159.12/ks.cfg
label linux text
kernel vmlinuz
append text initrd=initrd.img method=ftp://192.168.159.12/centos7
label linux rescue
kernel vmlinuz
append rescue initrd=initrd.img method=ftp://192.168.159.12/centos7" >> /var/lib/tftpboot/pxelinux.cfg/default
echo "############### 启动菜单文件已配置完成! ###############"
systemctl stop firewalld.service
echo "############### 系统防火墙已关闭! ###############"
setenforce 0
echo "############### 系统安全机制已关闭! ###############"
yum install -y system-config-kickstart
cp /opt/ks.cfg /var/ftp/ks.cfg
# 需提前准备好ks.cfg配置文件
echo "############### 自动应答文件配置完成! ###############"
echo "############### pxe自动装机环境准备完成! ###############"