sed:(stream editor)文本流编辑,sed是一个“非交互式的”面向字符流的编辑器。能同时处理多个文件多行的内容,可以不对原文件改动,把整个文件输入到屏幕,可以把只匹配到模式的内容输入到屏幕上。还可以对原文件改动,但是不会再屏幕上返回结果。
sed [参数] ‘命令’ file
p ##显示
d ##删除
a ##添加
c ##替换
i ##插入
显示p:
[root@desktop8 mnt]# sed -n '/^#/p' /etc/fstab 显示以#开头的行
#
# /etc/fstab
# Created by anaconda on Wed May 7 01:22:57 2014
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
[root@desktop8 mnt]# sed -n '/^#/!p' /etc/fstab 不显示以#开头的行
UUID=9bf6b9f7-92ad-441b-848e-0257cbb883d1 / xfs defaults 1 1
//172.25.8.100/smbshare /mnt/multiuser cifs defaults,credentials=/root/smbpasswd,sec=ntlmssp,multiuser 0 0
[root@desktop8 mnt]# sed -n '2,6p' /etc/fstab 显示第2行到第六行
#
# /etc/fstab
# Created by anaconda on Wed May 7 01:22:57 2014
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
[root@desktop8 mnt]# sed -n '2,6!p' /etc/fstab 不显示第2行到第6行
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=9bf6b9f7-92ad-441b-848e-0257cbb883d1 / xfs defaults 1 1
//172.25.8.100/smbshare /mnt/multiuser cifs defaults,credentials=/root/smbpasswd,sec=ntlmssp,multiuser 0 0
删除d:
[root@desktop8 mnt]# sed '/^#/d' /etc/fstab 显示删除以#开头后的结果
UUID=9bf6b9f7-92ad-441b-848e-0257cbb883d1 / xfs defaults 1 1
//172.25.8.100/smbshare /mnt/multiuser cifs defaults,credentials=/root/smbpasswd,sec=ntlmssp,multiuser 0 0
[root@desktop8 mnt]# sed '1,3d' /etc/fstab 显示删除1到3行后的结果
# Created by anaconda on Wed May 7 01:22:57 2014
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=9bf6b9f7-92ad-441b-848e-0257cbb883d1 / xfs defaults 1 1
//172.25.8.100/smbshare /mnt/multiuser cifs defaults,credentials=/root/smbpasswd,sec=ntlmssp,multiuser 0 0
添加a:
[root@desktop8 mnt]# vim file
[root@desktop8 mnt]# cat file
redhat
hello redhat
hellowestos
[root@desktop8 mnt]# sed '/hello/aby' file 在hello所在行后添加by
redhat
hello redhat
by
hellowestos
by
[root@desktop8 mnt]# sed 's/hello/hello world/g' file 将hello换成hello world显示出来
redhat
hello world redhat
hello worldwestos
[root@desktop8 mnt]# sed 's/hello/hello\nworld/g' file 将hello换成 hello+换行+world
redhat
hello
world redhat
hello
worldwestos
替换c:
[root@desktop8 mnt]# sed '/hello/chello world' file 将hello换成hello world
redhat
hello world
hello world
i插入
[root@desktop8 mnt]# sed '/hello/iworld' file 在hello所在行后插入world并显示
redhat
world
hello redhat
world
hellowestos
-i 替换
sed -i ‘s/westos/redhat/g’ passwd 将passwd文件中的所有westos改为redhat并保存
练习:修改http的端口
[root@desktop8 脚本]# sh xiugaiduankou.sh
请输入要修改的端口号:8080
端口已被修改为8080
[root@desktop8 脚本]# cat xiugaiduankou.sh
#!/bin/bash
read -p "请输入要修改的端口号:" a
sed -i "s/^Listen/cListen $a/g" /etc/httpd/conf/httpd.conf && echo "端口已被修改为$a"
#########awk报告生成器########
awk处理机制:根据模式一次从文件中抽取一行文本,对这行文本进行切片(默认使用空白字符作为分隔符)
例如:redhat hello world
redhat表示$1 hello表示$2 world表示$3
[root@desktop8 mnt]# cat file
hello world redhat xupt
[root@desktop8 mnt]# awk '{print $1}' file
hello
[root@desktop8 mnt]# awk '{print $2}' file
world
[root@desktop8 mnt]# awk '{print $3}' file
redhat
[root@desktop8 mnt]# awk '{print $4}' file
xupt
[root@desktop8 mnt]# awk '{print $4 $1}' file
xupthello
[root@desktop8 mnt]# awk '{print $4,$1}' file
xupt hello
awk -F: ‘{print $1,$3}’ /etc/passwd 指定以冒号为分隔符输出第一列和第三列
[root@desktop8 mnt]# awk -F: '{print $1,$3}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
......
awk常用变量
awk ‘{print FILENAME,NR}’ /etc/passwd ##输出文件名,和当前操作的行号
[root@desktop8 mnt]# awk '{print FILENAME,NR}' /etc/passwd
/etc/passwd 1
/etc/passwd 2
/etc/passwd 3
/etc/passwd 4
/etc/passwd 5
/etc/passwd 6
.............
awk -F: ‘{print NR,NF}’ /etc/passwd ##输出每次处理的行号,以及当前以":"为分隔符的字段个数
[root@desktop8 mnt]# awk -F: '{print NR,NF}' /etc/passwd
1 7
2 7
3 7
4 7
5 7
6 7
.....
总结:awk ‘{print “第NR行”,“有NF列”}’ /etc/passwd
BEGIN{}:读入第一行文本之前执行的语句,一般用来初始化操作
{}:逐行处理
END{}:处理完最后一行文本后执行,一般用来处理输出结果
[root@desktop8 mnt]# awk 'BEGIN { a=1;print a+10 }'
11
awk ‘BEGIN{print “redhat”} {print NR;print } END{print “westos”}’ file 打印行号和内容,并在执行前打印redhat,执行后打印westos,且要加双引号。
[root@desktop8 脚本]# cat file
hello world
[root@desktop8 脚本]# awk 'BEGIN{print "redhat"} {print NR;print } END{print "westos"}' file
redhat
1
hello world
westos
awk ‘/bash$/{print}’ /etc/passwd 打印出/etc/passwd文件以bash结尾的行
awk ‘/^root/{print}’ /etc/passwd 打印出/etc/passwd文件以root开头的行
[root@desktop8 脚本]# awk '/bash$/{print}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
student:x:1000:1000:Student User:/home/student:/bin/bash
liming:x:1001:1001::/home/liming:/bin/bash
apple:x:1002:1002::/home/apple:/bin/bash
hellow:x:1003:1003::/home/hellow:/bin/bash
oo:x:1004:1004::/home/oo:/bin/bash
[root@desktop8 脚本]# awk '/^root/{print}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
awk ‘NR==3 {print}’ /etc/passwd 输出第三行
[root@desktop8 脚本]# awk 'NR==3 {print}' /etc/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin
awk ‘NR % 2 == 0 {print}’ /etc/passwd 输出偶数行
[root@desktop8 脚本]# awk 'NR % 2 == 0 {print}' /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
halt:x:7:0:halt:/sbin:/sbin/halt
operator:x:11:0:operator:/root:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
.......................................
awk ‘NR >= 3 && NR <=5 {print}’ /etc/passwd 输出/etc/passwd文件的第三行到第5行
[root@desktop8 脚本]# awk 'NR >= 3 && NR <=5 {print}' /etc/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
输出一个文件的所有字段
[root@desktop8 脚本]# awk 'BEGIN {i=0} {i+=NF} END{print i}' /etc/passwd
78
if单分支语句
awk -F: ‘BEGIN{i=0}{if(
7
=
/
b
a
s
h
7=/bash
7=/bash/){i++}}END{print i}’ /etc/passwd ##统计登录shell为bash的用户
[root@desktop8 脚本]# awk -F: 'BEGIN{i=0}{if($7=/bash$/){i++}}END{print i}' /etc/passwd
6
if双分支
awk -F: ‘BEGIN{i=0;j=0}{if($3<=500){i++}else{j++}}END{print i,j}’ /etc/passwd ##统计uid小于等于500和大于500的用户个数
[root@desktop8 脚本]# awk -F: 'BEGIN{i=0;j=0}{if($3<=500){i++} else {j++}} END{print i,j}' /etc/passwd
32 14
for循环
[root@desktop8 脚本]# awk 'BEGIN{for(i=0;i<=5;i++) {print i}}'
0
1
2
3
4
5
seq
seq 是Linux 中一个预设的外部命令,一般用作一堆数字的简化写法
[root@desktop8 脚本]# seq 5 输出1-5
1
2
3
4
5
[root@desktop8 脚本]# seq 0 5 输出0-5
0
1
2
3
4
5
[root@desktop8 脚本]# seq 1 2 10 在1-10之间每隔两个数取一个
1
3
5
7
9
练习:编写一个倒计时的脚本
[root@desktop8 脚本]# cat test.sh
#!/bin/bash
read -p "请输入分和秒:" fen miao
c=$[fen*60+miao]
for((i=c;i>0;i--))
do
echo -n "剩余$[i/60]分 $[i%60]秒"
echo -ne "\r"
sleep 1
done
[root@desktop8 脚本]# sh test.sh
请输入分和秒:3 10
^C余2分 37秒
[root@desktop8 脚本]#
while循环
创建20个用户,用户名为westos1到westos20,密码都为123456
[root@desktop8 脚本]# cat useradd.sh
#!/bin/bash
a=1
while ((a<=20))
do
useradd westos$a
echo "123456" | passwd --stdin westos$a &> /dev/null 将此命令执行后的输出不显示
a="$[a+1]"
done
[root@desktop8 脚本]# sh useradd.sh 执行脚本
[root@desktop8 脚本]# cat /etc/passwd
westos1:x:1006:1006::/home/westos1:/bin/bash
westos2:x:1007:1007::/home/westos2:/bin/bash
westos3:x:1008:1008::/home/westos3:/bin/bash
westos4:x:1009:1009::/home/westos4:/bin/bash
westos5:x:1010:1010::/home/westos5:/bin/bash
westos6:x:1011:1011::/home/westos6:/bin/bash
westos7:x:1012:1012::/home/westos7:/bin/bash
westos8:x:1013:1013::/home/westos8:/bin/bash
westos9:x:1014:1014::/home/westos9:/bin/bash
westos10:x:1015:1015::/home/westos10:/bin/bash
westos11:x:1016:1016::/home/westos11:/bin/bash
westos12:x:1017:1017::/home/westos12:/bin/bash
westos13:x:1018:1018::/home/westos13:/bin/bash
westos14:x:1019:1019::/home/westos14:/bin/bash
westos15:x:1020:1020::/home/westos15:/bin/bash
westos16:x:1021:1021::/home/westos16:/bin/bash
westos17:x:1022:1022::/home/westos17:/bin/bash
westos18:x:1023:1023::/home/westos18:/bin/bash
westos19:x:1024:1024::/home/westos19:/bin/bash
westos20:x:1025:1025::/home/westos20:/bin/bash
练习:打印99乘法表
[root@desktop8 脚本]# vim 99chengfa.sh
[root@desktop8 脚本]# cat 99chengfa.sh
#!/bin/bash
for((i=1;i<=9;i++))
do
for((j=1;j<=i;j++))
do
echo -ne $i*$j="$[i*j]\t"
done
echo -e "\r"
done
[root@desktop8 脚本]# sh 99chengfa.sh
1*1=1
2*1=2 2*2=4
3*1=3 3*2=6 3*3=9
4*1=4 4*2=8 4*3=12 4*4=16
5*1=5 5*2=10 5*3=15 5*4=20 5*5=25
6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36
7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49
8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64
9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81
练习:检测172.25.254网络号下1-8号主机是否可以ping通
[root@desktop8 脚本]# cat ping.sh
#!/bin/bash
#j=0
for((i=1;i<=8;i++))
do
ping -c1 -w1 172.25.254.$i &> /dev/null && echo 172.25.254.$i is up || echo 172.25.254.$i is down
done
[root@desktop8 脚本]# sh ping.sh
172.25.254.1 is down
172.25.254.2 is down
172.25.254.3 is down
172.25.254.4 is down
172.25.254.5 is down
172.25.254.6 is down
172.25.254.7 is down
172.25.254.8 is up
if-else语句
[root@desktop8 脚本]# cat if.sh
#!/bin/bash
if [ "$1" = linux ];then
echo "welcome $1"
elif [ "$1" = redhat ];then
echo "welcome $1"
else
echo "who are you?"
fi
[root@desktop8 脚本]# sh if.sh linux
welcome linux
[root@desktop8 脚本]# sh if.sh redhat
welcome redhat
[root@desktop8 脚本]# sh if.sh asdsad
who are you?
case
当条件很多时,就可以使用case语句,例如:在上面的条件下,我再加入两个条件,就可以使用case语句
[root@desktop8 脚本]# cat case1.sh
#!/bin/bash
case $1 in
student|kiosk|linux|redhat)
echo "welcome $1"
;;
*)
echo "who are you?"
;;
esac
[root@desktop8 脚本]# sh case1.sh linux
welcome linux
[root@desktop8 脚本]# sh case1.sh kios
who are you?
[root@desktop8 脚本]# sh case1.sh kiosk
welcome kiosk
[root@desktop8 脚本]# sh case1.sh student
welcome student
练习:编写一个脚本,选择A时输出eth0网卡的ip,选择B时输出/dev/vda1剩余内存,选择C时输出系统运行时间,选择Q时退出。
[root@desktop8 脚本]# cat case.sh
#!/bin/bash
while true
do
read -p "please input:" a
case $a in
A|a)
echo `ifconfig eth0| grep broad| awk '{print $2}'`
;;
B|b)
echo `df | grep /dev/vda1 | awk '{print $4}'`
;;
C|c)
echo `uptime`
;;
Q|q)
exit 1
;;
esac
done
[root@desktop8 脚本]# sh case.sh
please input:a
172.25.254.108
please input:b
6853784
please input:c
06:26:02 up 9:51, 2 users, load average: 0.00, 0.01, 0.05
please input:q