三剑客、shell脚本

天涯浪子 提交于 2019-12-27 01:07:28

一、三剑客(sed,awk,grep)

(一)三剑客-sed

sed定义 :字符流编辑器:stream editor

sed功能与版本:

①处理纯文本文件,日志,配置文件等==》linux

②增加、删除、修改、查询

③sed --version,GNU sed version 4.2.1

(1)sed语法格式:

sed 【选项】【sed指令】【输入文件】

sed -i.bak 's#oldboy#oldgirl#g' oldboy.txt

i :sed命令的参数

s:sed命令/指令

g:--小尾巴/修饰

(2)sed执行过程:

①把第一行读取到内存中(模式空间)

②判断是否是我要的这一行是否满足条件(如果不是,重新读取)

③执行sed里面命令s,d,i。

④sed命令会默认显示/输出当前内存,默认输出--》显示到屏幕

⑤继续读取下一行直到读取到文件的最后一行。

(3)sed常用功能之p(print)

查看某一行内容:
[root@oldboy-01 oldboy]# sed -n '1p' person.txt 
101,oldboy,CEO
[root@oldboy-01 oldboy]# sed  '1p' person.txt #如果不带参数n,显示全部内容
101,oldboy,CEO
101,oldboy,CEO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO
查看2-4行内容:
[root@oldboy-01 oldboy]# sed -n '2,4p' person.txt 
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
查看包含oldboy的行:
[root@oldboy-01 oldboy]# sed -n '/oldboy/p' person.txt 
101,oldboy,CEO
查看包含oldboy至以104开头的行内容:
[root@oldboy-01 oldboy]# sed -n '/oldboy/,/^104/p' person.txt 
101,oldboy,CEO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO

(4)sed常用命令参数-r

-r sed选项,支持扩展正则表达式(|,())

默认情况下,sed只支持基本正则表达式。

[root@oldboy-01 oldboy]# egrep 'oldboy|yy' person.txt 
101,oldboy,CEO
104,yy,CFO
[root@oldboy-01 oldboy]# sed -rn '/oldboy|yy/p' person.txt 
101,oldboy,CEO
104,yy,CFO
[root@oldboy-01 oldboy]# 

总结:①查询某一行,查询某一个范围:1p,2,4p

②通过正则表达式查询范围

sed -n '/oldboy/,/^104/p' person.txt

③sed命令通过正则表达式进行过滤,相当于egrep

sed显示不连续的行内容:

[root@oldboy-01 oldboy]# sed -n '1p;3p;4p' person.txt 
101,oldboy,CEO
103,Alex,COO
104,yy,CFO
[root@oldboy-01 oldboy]# 

(5)sed常用功能之增加a(append)和i(insert)插入

a:在指定行后添加一行或者多行文本。

i:在指定行前添加一行后者多行文本。

[root@oldboy-01 oldboy]# sed '2a 106,xiaoyu,cxo' person.txt 
101,oldboy,CEO
102,zhangyao,CTO
106,xiaoyu,cxo
103,Alex,COO
104,yy,CFO
105,feixue,CIO
[root@oldboy-01 oldboy]# sed '2i 107,zhangsan,xxo' person.txt 
101,oldboy,CEO
107,zhangsan,xxo
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO
[root@oldboy-01 oldboy]#

sed 中的$表示最后一行:

在最后一行后增加内容方法1:(增加多行使用/n换行)

[root@oldboy-01 oldboy]# sed '$a new,new,new/nold,old,old' person.txt 
101,oldboy,CEO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO
new,new,new/nold,old,old
[root@oldboy-01 oldboy]# 

在最后一行后增加内容方法2:

[root@oldboy-01 oldboy]# cat>>person.txt<<EOF

(6)sed常用功能之删除与去除空行

-d:sed删除命令参数

删除一行:
[root@oldboy-01 oldboy]# sed '$d' person.txt 
101,oldboy,CEO
102,zhangyao,CTO
106,xiaoyu,cxo
103,Alex,COO
104,yy,CFO
删除多行:
[root@oldboy-01 oldboy]# sed '2,3d' person.txt 
101,oldboy,CEO
103,Alex,COO
104,yy,CFO
105,feixue,CIO
[root@oldboy-01 oldboy]# 

删除空行:

sed '/^$/d' person.txt

显示空行:

sed -n '/^$/p' person.txt

显示非空行:

sed -n '/^$/!p' person.txt

删除最后一行:

sed '$d' person.txt

删除非最后一行:

sed '$!d' person.txt

显示非空行(awk):

awk '!/^$/' person.txt

(7)sed常用功能之替换与引用变量

s:单独使用,将每一行中第一处匹配的字符串进行替换。

g:global每一行进行全部替换,sed指令s的替换标志之一(全局替换)

[root@oldboy-01 oldboy]# sed 's#o#AAA#g' person.txt 

修改文件参数:-i

自动备份:

-i.ori:表示先备份源文件,在修改文件的内容。

变量替换:

单引号:所见即所得

双引号:特殊符号会被解析。

[root@oldboy-01 oldboy]# x=oldboy
[root@oldboy-01 oldboy]# y=oldgirl
[root@oldboy-01 oldboy]# sed "s#$x#$y#g" person.txt 
101,oldgirl,CEO
102,zhangyao,CTO
106,xiaoyu,cxo
103,Alex,COO
104,yy,CFO
105,feixue,CIO
[root@oldboy-01 oldboy]#

方向引用:

():的功能可以记住正则表达式的一部分。

扩展正则,使用-r

\1引用第一个小括号中的匹配内容,\2引用第二个小括号中匹配内容,sed最多可以记住9个。

案例:echo 'i am oldboy teacher',如果想保留这一行单词oldboy。

(二)三剑客-awk

(1)awk基础

awk版本:

[root@oldboy-01 ~]# awk --version

GNU Awk 3.1.7

awk实例:

[root@oldboy-01 ~]# awk -F ':' 'NR==2{print $1,$2}' /etc/passwd
bin x

awk格式:

awk 参数 ‘模式{动作}’ 文件

awk 参数 ‘条件(找谁){干啥}’ 文件

awk执行过程:

①读入一行

②模式(条件)是我要处理的行吗?

是:对读入行执行动作里命令

否:重复上面过程直到最后一个文件结尾。

④读取下一行

⑤end模块--结束

模式匹配:模式和动作

案例①:显示xiaoyu的姓氏和id号(花括号外面是条件):

[root@oldboy-01 files]# awk '/Xiaoyu/{print $1,$2,$3}' reg.txt 
Zhang Xiaoyu 390320151

第二列包含xiaoyu:波浪线是匹配或者包含的意思

[root@oldboy-01 files]# awk '$2~/Xiaoyu/' reg.txt 
Zhang Xiaoyu    390320151  :155:90:201
[root@oldboy-01 files]# 


[root@oldboy-01 files]# awk '/Xiaoyu/' reg.txt #任意一列包含
Zhang Xiaoyu    390320151  :155:90:201
[root@oldboy-01 files]# awk '$0~/Xiaoyu/' reg.txt #$0,表示这一行。
Zhang Xiaoyu    390320151  :155:90:201

案例②:显示所有以41开头的id号码的人的全名和id号码:

[root@oldboy-01 files]# awk '$3~/^41/' reg.txt 
Zhang Dandan    41117397   :250:100:175
Liu   Bingbing  41117483   :250:100:175
[root@oldboy-01 files]# awk '$3~/^41/{print $1,$2,$3}' reg.txt 
Zhang Dandan 41117397
Liu Bingbing 41117483
[root@oldboy-01 files]# 

案例③:显示所有ID号码最后一位数字是1或5的人全名

[root@oldboy-01 files]# awk '$3~/[15]$/' reg.txt 
Zhang Xiaoyu    390320151  :155:90:201
Wu    Waiwai    70271111   :250:80:75
Wang  Xiaoai    3515064655 :50:95:135
Li    Youjiu    918391635  :175:75:300
Lao   Nanhai    918391635  :250:100:175
[root@oldboy-01 files]# awk '$3~/[15]$/{print $1,$2}' reg.txt 
Zhang Xiaoyu
Wu Waiwai
Wang Xiaoai
Li Youjiu
Lao Nanhai
[root@oldboy-01 files]# awk '$3~/(1|5)$/{print $1,$2}' reg.txt 
Zhang Xiaoyu
Wu Waiwai
Wang Xiaoai
Li Youjiu
Lao Nanhai
[root@oldboy-01 files]# 

案例④:显示xiaoyu的捐款,每个值时都是以$开头,如¥520

awk 中替换用法:gsub(/目标/,"替换成什么",第几列)

[root@oldboy-01 files]# awk '{gsub(/:/,"$",$4);print}' reg.txt 
Zhang Dandan 41117397 $250$100$175
Zhang Xiaoyu 390320151 $155$90$201
Meng Feixue 80042789 $250$60$50
Wu Waiwai 70271111 $250$80$75
Liu Bingbing 41117483 $250$100$175
Wang Xiaoai 3515064655 $50$95$135
Zi Gege 1986787350 $250$168$200
Li Youjiu 918391635 $175$75$300
Lao Nanhai 918391635 $250$100$175
[root@oldboy-01 files]# awk '$2~/Xiaoyu/{gsub(/:/,"$",$4);print}' reg.txt 
Zhang Xiaoyu 390320151 $155$90$201
[root@oldboy-01 files]# 

(2)awk 的特殊模式BEGIN和END:

BEGIN{} BEGIN里面的内容,会在awk读取内容之前运行。

测试、计算。

[root@oldboy-01 files]# awk 'BEGIN{print "this is kt"}'
this is kt
[root@oldboy-01 files]# awk 'BEGIN{print "this is kt"} {print NR,$0}' reg.txt 
this is kt
1 Zhang Dandan    41117397   :250:100:175
2 Zhang Xiaoyu    390320151  :155:90:201
3 Meng  Feixue    80042789   :250:60:50
4 Wu    Waiwai    70271111   :250:80:75
5 Liu   Bingbing  41117483   :250:100:175
6 Wang  Xiaoai    3515064655 :50:95:135
7 Zi    Gege      1986787350 :250:168:200
8 Li    Youjiu    918391635  :175:75:300
9 Lao   Nanhai    918391635  :250:100:175
[root@oldboy-01 files]# 

END{}:END{}里面的内容,会在awk读取完文件的最后一行之后运行。

用来显示最终结果。先计算,end显示结果。

案例①:统计/etc/services文件里面的空行数量。

i=i+1,i++一般用于统计。

[root@oldboy-01 files]# awk '/^$/{i=i+1;print i}' /etc/services 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@oldboy-01 files]# awk '/^$/{i=i+1}END{print i}' /etc/services 
16

案例分析:

(百度面试)处理以下文件内容,将域名取出并根据域名进行计数排序处理。

awk数组进行统计:如hotel[110]='zhangsan'

[root@oldboy-01 files]# awk 'BEGIN{h[110]="lee";h[114]="xo";print h[110],h[114]}'
lee xo

创建场景:

[root@oldboy-01 files]# cat>> url.txt << EOF
> http://www.etiantian.org/index.html
> http://www.etiantian.org/1.html
> http://post.etiantian.org/index.html
> http://mp3.etiantian.org/index.html
> http://www.etiantian.org/3.html
> http://post.etiantian.org/2.html
> EOF

案例:

[root@oldboy-01 files]# awk -F "[/.]+" '{print $2}' url.txt 
www
www
post
mp3
www
post
[root@oldboy-01 files]# awk -F "[/.]+" '{h[$2]=h[$2]+1;print h["www"]}' url.txt 
1
2
2
2
3
3
[root@oldboy-01 files]# awk -F "[/.]+" '{h[$2]=h[$2]+1;print h["www"]}' url.txt 
1
2
2
2
3
3
[root@oldboy-01 files]# awk -F "[/.]+" '{h[$2]=h[$2]+1}END{print h["www"],h["post"],h["mp3"]}' ur.txt 
3 2 1
[root@oldboy-01 files]# awk -F "[/.]+" '{h[$2]=h[$2]+1}END{for(x in h) print x}' url.txt 
www
mp3
post
[root@oldboy-01 files]# awk -F "[/.]+" '{h[$2]=h[$2]+1}END{for(x in h) print x ,h[x]}' url.txt 
www 3
mp3 1
post 2

练习题:统计secure系统文件分析。谁在破解你的密码(failed password 每个ip地址出现的次数)

分析系统每个用户被破解的次数。

(3)总结:

①awk数组进行统计,i++,i=i+1;i=i+$n

②awk执行过程

③awk通过正则作为模式

④BEGIN和END特殊模式

二、shell编程

(一)shell基础知识

命令解释器:/bin/bash

file 查看文件类型,是否为shell脚本。

①脚本统一放在/server/scripts

②推荐使用vim编辑器

③脚本第一行:(#!/bin/bash,默认是bash解释器。#des,#author:,#time,#version:)

变量:见名知意(字母开头,字母,数字,下划线组成)

取变量内容:如:${week},使用花括号引用变量。

普通变量:局部变量

环境变量:全局变量,大写的PATH,LANG,PS

局部变量变成全局变量:export 变量

使用env,查看全局变量。

取消变量;unset 变量

与环境变量相关的文件和目录

全局环境变量配置文件:

/etc/profile

/etc/bashrc

/etc/profile.d/

用户登录到系统会运行这个目录下的脚本

脚本要有执行权限。

用户环境变量配置文件:

~/.bash_profile

~/.bashrc

(二)特殊变量

位置变量:$:0,n,#:

0:表示脚本名称,包括路径。

n:第n个参数。

($#)表示一共多少个参数,参数个数。

进程状态变量:($?)显示上一个命令执行结果。

命令执行正确:0

命令执行错误:非0

(三)shell编程之变量赋值方法:read

交互式赋值:

格式:read -p "input x y:" x y

[root@oldboy-01 files]# cat  xxyy.sh
#!/bin/bash
read -p "input x y:" x y
echo $x $y
[root@oldboy-01 files]# sh xxyy.sh
input x y:10 50
10 50
[root@oldboy-01 files]# 

(四)shell脚本循环

条件表达式:格式:[]

判断文件:f,d

[-f /root/oldboy.alex.txt] 是否为文件

[ -d /root ] 目录是否存在

判断整数:

等于equal:-eq

不等于not equal:-ne

大于greater than: -gt

大于等于greater equal :-ge

小于less than:-lt

小于等于less equal:-le

简单案例:判断命令行参数个数等于2

[root@oldboy-01 files]# cat /server/scripts/arg.sh
#!/bin/bash
[ $# -eq 2 ] && echo "arg:" $#
[root@oldboy-01 files]# sh /server/scripts/arg.sh a b
arg: 2
[root@oldboy-01 files]# sh /server/scripts/arg.sh a b c
[root@oldboy-01 files]# 

案例:如果/oldboy目录不存在则创建

[ -d /oldboy ] || mkdir -p /oldboy

如果/root/oldboy.txt存在则提示文件已存在。

[ -f /root/oldboy.txt ] && echo "file esists"

shell编程之if判断:if elif,else,fi:

[root@oldboy-01 files]# sh /server/scripts/comp.sh  1 1
1 equal 1
[root@oldboy-01 files]# sh /server/scripts/comp.sh  1 4
1 less than 4
[root@oldboy-01 files]# sh /server/scripts/comp.sh  1 0
1 greater than 0
[root@oldboy-01 files]# cat /server/scripts/comp.sh 
#!/bin/bash
num1=$1
num2=$2
if [ $# -ne 2 ];then
   echo "usage:please input 2 number:num1 num2"
   exit
fi

if [ $num1 -gt $num2 ];then
   echo $num1 greater than $num2
elif [ $num1 -lt $num2 ];then
   echo $num1 less than $num2
else
   echo $num1 equal  $num2
fi
[root@oldboy-01 files]# 

shell编程之条件与判断表达式小结(先画流程图)

1、条件表达式

整数比较:-eq,-gt,-ge,-ne,-lt,-le

文件比较:

[ -d /oldboy ]

[-f /oldboy/oldboy.txt ]

2、判断

if ,elif,else,fi

shell编程之for循环:(做相同的事情)

格式:for 变量名字 in 列表

do

命令

done

[root@oldboy-01 files]# for num in {01..100}
> do
>    echo "the $num number is :$num"
> done
the 001 number is :001

案例:优化linux开机启动项目,只保留crond,sshd,network,rsyslog,systat,其他都关闭。

chkconfig 服务 off

[root@oldboy-01 scripts]# sh  chk.sh
[root@oldboy-01 scripts]# chkconfig | grep 3:on
crond           0:off   1:off   2:on    3:on    4:on    5:on    6:off
network         0:off   1:off   2:on    3:on    4:on    5:on    6:off
rsyslog         0:off   1:off   2:on    3:on    4:on    5:on    6:off
sshd            0:off   1:off   2:on    3:on    4:on    5:on    6:off
[root@oldboy-01 scripts]# cat chk.sh
#!/bin/bash
for name in $(chkconfig | egrep "crond|sshd|rsyslog|network|systat" -v | awk '{print $1}')
do
    chkconfig $name off
done
[root@oldboy-01 scripts]#

(五)linux运行脚本的技巧:

看脚本运行过程:-x:有加号,运行过程,没有加号表示显示桌面。

①特殊变量:($n,0,#,?)

②普通变量命名规则

③普通变量和环境变量区别

④与用户有关的文件和目录

⑤条件表达式,判断,循环

⑥优化系统启动项目

⑦批量添加用户并设置随机密码

三、网络

协议的源端口随机产生,范围为:

[root@oldboy-01 ipv4]# cat  /proc/sys/net/ipv4/ip_local_port_range 

4000    65000

域名的层次级别:

第一个级别:称为根域名服务器(13个)

第二个级别:称为顶级域名服务器(一级域名服务器)com,cn,gov

第三个级别:称为二级域名服务器(授权DNS服务器).baidu.com

第四个级别:称为虚拟机主机信息www.baidu.com

使用dig命令查看域名解析过程。

nslookup 域名解析

host 域名解析

ping 域名解析

DNS配置地方:

/etc/sysconfig/network-scripts/ifc-eth0

/etc/resolv.conf

重启网卡:

ifdown eth0 && ifup eth0

/etc/init.d/network restart

系统默认路由:

route -n
route add default gw 10.0.0.254
route del default gw 10.0.0.254
route add -net 172.16.1.0/24 gw 10.0.0.254
route add -host 172.16.2.2 gw 10.0.0.254

网卡多地址配置:

方法1:
ifconfig eth0:1 10.1.0.8/24 up
ifconfig eth0:1 down
方法2
ip addr add 10.1.0.8/24 broadcast 10.1.0.255 dev eth0

网络常用命令:

ifconfig
ip addr
route
hostname
hostname -I
netstat
ss -lntp | grep sshd(centos7)
netstat -lntp | grep sshd
ss -lntp | grep sshd
ping -c 4 10.0.0.1
[root@oldboy-01 ipv4]# ping 10.0.0.1 -c 4 -i 3
(ping 4次,间隔3s)
[root@oldboy-01 ipv4]# ping 10.0.0.1 -c 4 -i 3 -q #不显示过程
[root@oldboy-01 ipv4]# ping 10.0.0.1 -f -c 1000
(-f 极限ping测,很快出结果)
tracroute www.baidu.com
tracert www.baidu.com
telnet 22 #测试端口
[root@oldboy-01 ipv4]# nmap 10.0.0.202 -p 10-40
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!