目录
1.Shell基础知识
2.判断和循环语句
3.函数与中断、字符串的处理
4.正则表达式、SED文本编辑器
5.AWK数据过滤与数据分析
---------------------------------------
1. Shell基础知识
1)常见shell解释器
/bin/bash
/bin/sh
/bin/csh
/bin/tcsh
2)通过usermod、chsh可以更改登陆Shell
3)标准输入与输出的重定向
> :标准输出,覆盖写入
>>:标准输出,追加写入
2>:错误输出,覆盖写入
2>>:错误输出,追加写入
&>:标准和错误一起纯输出,覆盖写入,和 > txt 2>&1 效果一样
4)source命令执行脚本文件,不会启动子进程,通过pstree查看进程树
5)环境变量
存储在/etc/profile或~/.bash_profile
命令env可以列出所有环境变量
常见环境变量:PATH、PWD、USER、UID、HOME、SHELL
6)位置变量
存储脚本执行时的参数
使用$n表示,n为数字序列号
$1、\(2、...、\){10}、${11}、...
eg:通过位置变量创建系统账户,配置密码
useradd "$1"
echo "$2" | passwd --stdin "$1"
7)预定义变量
![]()
8)区分三种定界符
双引号 " ":允许扩展,以 $ 引用其他变量
单引号 ' ':禁用扩展,即便 $ 也视为普通字符
反引号 ` `:将命令的执行输出作为变量值,$()与反引号等效
9)read 从键盘读入变量值完成赋值
格式: read [ -p "提示信息" ] 变量名
-p可选,-t 可指定超时秒数,-s设置是否在终端显示输入的内容
[root@localhost ~]# vim /root/shell/day01/read.sh
#!/bin/bash
read -p "请输入用户名:" name
read -p "请输入密码:" -s pass
useradd "$name"
echo "$pass" | passwd --stdin "$name"
[root@localhost ~]# bash /root/shell/day01/read.sh
请输入用户名:jerry
请输入密码:
10)变量作用域
==>局部变量
新定义的变量默认只在当前Shell环境中有效,无法在子Shell环境中使用
==>全局变量
全局变量在当前Shell及子Shell环境中均有效
[root@localhost ~]# x=11 #定义局部变量
[root@localhost ~]# sh #进入子Shell
sh-4.2# echo $x #无此变量,输出为空
sh-4.2# exit #退出子Shell
[root@localhost ~]# export x=11 #定义全局变量
11)计算
$[]算式替换
使用 $[ ] 或 $(( )) 表达式
格式:$[整数1 运算符 整数2 .. ..]
计算结果替换表达式本身,可结合echo命令输出
Bash内建机制仅支持整数运算,不支持小数运算
[root@localhost ~]# echo $[3.5+2.2]
-bash: 3.5+2.2: 语法错误: 无效的算术运算符 (错误符号是 ".5+2.2")
我们可以通过计算器软件bc实现小数运算
如果没有该软件则需要使用yum安装
bc支持交互式和非交互式两种方式计算,scale=n可以约束小数位
bc计算器
scale=n可以约束小数位
quit退出交互式计算
12)echo回显
-n选项:不换行
-e选项:支持扩展属性
[root@localhost ~]# echo "hello world" #换行
hello world
[root@localhost ~]# echo -n "hello world" #不换行
hello world[root@localhost ~]#
[root@localhost ~]# echo -e "\033[31mOK\033[0m" #红色显示OK
[root@localhost ~]# echo -e "\033[32mOK\033[0m" #绿色显示OK
[root@localhost ~]# echo -e "\033[34mOK\033[0m" #蓝色显示OK
2.判断和循环语句
1)判断
==>字符串比较
· 是否为空 [ -z 字符串 ]
· 等于[ 字符串1 == 字符串2 ]
· 不等于[ 字符串1 != 字符串2 ]
==>整数值比较
![]()
==>文件状态
![]()
==>基础命令:
tr -s 删除多余重复的字串
[root@localhost ~]# echo "a b c" | tr -s " " #删除多余的空格
[root@localhost ~]# echo "aaacaaaaaq" | tr -s "a" #删除多余的a
==>cut过滤数据
[root@localhost ~]# cut -d: -f1 /etc/passwd
#以冒号为分隔,过滤第一列
2)for循环
for 变量 in 值列表
do
命令序列
done
------------------------------
for ((初值;条件;步长))
do
命令序列
done
3)case语法
case 变量 in
模式1)
命令序列1 ;;
模式2)
命令序列2 ;;
.. ..
*)
默认命令序列
esac
4)数组
数组也是一个变量,是一个有点特殊的变量
存储多个数据的集合就是数组
[root@localhost ~]# test=(11 22 33) #定义数组
[root@localhost ~]# echo ${test[0]} #调用数组的值
11
[root@localhost ~]# echo ${test[1]}
22
[root@localhost ~]# echo ${test[2]}
33
5)多进程命令
[root@localhost ~]# vim /root/shell/day03/mutiping.sh
#!/bin/bash
myping() {
ping -c3 -i0.2 -W1 $1 &>/dev/null
if [ $? -eq 0 ];then
echo "$1 is up"
else
echo "$1 is down"
fi
}
for i in {1..254}
do
myping "192.168.4.$i" &
done
wait
#使用&符号,将执行的函数放入后台执行,wait等待所有后台进程结束后退出脚本
3.函数与中断、字符串的处理
1)脚本的中断和退出
continue可以结束单次循环
break可以结束循环体
exit可以退出脚本
[root@localhost ~]# for i in {1..5}
do
[ $i -eq 3 ] && continue
echo $i
done
echo over
2)字符串处理
==>字符串截取
${变量:起始位置:长度}
[root@localhost ~]# echo ${#phone} #统计变量长度
11
[root@localhost ~]# echo ${phone:0:3}
138
[root@localhost ~]# echo ${phone:3:3}
123
[root@localhost ~]# echo ${phone:4}
2345678
[root@localhost ~]# echo ${phone:4:-2}
23456
==>字符串替换
替换1个结果
${变量/旧字串/新字串}
替换全部结果
${变量//旧字串/新字串}
[root@localhost ~]# phone=13812345678
[root@localhost ~]#
[root@localhost ~]# echo ${phone/3/X}
1X812345678
[root@localhost ~]# echo ${phone//3/X}
1X812X45678
==>字符串掐头
从左向右,最短匹配删除
${变量#关键词}
从左向右,最长匹配删除
${变量##关键词}
提示:对变量掐头不会改变变量原有的值!
[root@localhost ~]# A=`head -1 /etc/passwd`
[root@localhost ~]# echo $A
root:x:0:0:root:/root:/bin/bash
[root@localhost ~]# echo ${A#*:}
x:0:0:root:/root:/bin/bash
[root@localhost ~]# echo ${A##*:}
/bin/bash
==>字符串去尾
从右向左,最短匹配删除
${变量%关键词}
从右向左,最长匹配删除
${变量%%关键词}
[root@localhost ~]# A=`head -1 /etc/passwd`
[root@localhost ~]# echo $A
root:x:0:0:root:/root:/bin/bash
[root@localhost ~]# echo ${A%:*}
root:x:0:0:root:/root
[root@localhost ~]# echo ${A%%:*}
root
3)变量初始化
变量有值,则返回该变量的值
变量无值,则返回初始值
格式:${变量:-关键词}
[root@localhost ~]# X=123
[root@localhost ~]# echo ${X:-xyz}
123
[root@localhost ~]#
[root@localhost ~]# echo ${ABC:-xyz}
xyz
4)生产随机密码的方法
==>子串截取生产随机密码
[root@localhost ~]# vim /root/shell/day03/pass.sh
#!/bin/bash
#定义变量:10个数字+52个字母. #用随机数对62取余数,返回的结果为[0-61].
key="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
pass=""
for i in {1..10}
do
num=$[RANDOM%${#key}]
tmp=${key:num:1}
pass=${pass}${tmp}
done
echo $pass
==>使用命令生成随机密码
uuidgen
openssl
[root@localhost ~]# uuidgen
ebf97979-e2c5-4cfe-abdc-d97f84623796
[root@localhost ~]# openssl rand -base64 10
emwHlGEjQDv0qw==
==>使用随机设备文件(/dev/random、/dev/urandom)
tr命令可以对数据进行替换、删除等操作
-c:取反、-d:删除
[root@localhost ~]# tr -cd '0-9a-zA-Z' < /dev/urandom | head -c 10
#删除随机数据中不是数字、小写字母、大写字母的数据
#在截取出来的字串中提取前10个字符
4.正则表达式、SED文本编辑器
1)正则表达式
==>基本正则
![]()
==>扩展正则
![]()
==>Perl兼容的正则
![]()
==>grep用法
用法:grep [选项] 匹配模式 [文件]…
常用选项:
-i 忽略大小写
-v 取反匹配
-w 匹配单词
-q 静默匹配,不将结果显示在屏幕
2)sed(Stream Editer,流式编辑器)
==>特点
非交互式
逐行处理
可以对文本进行增、删、改、查等操作
==>语法:
sed [选项] '[定位符]指令' 文件名
命令 | sed [选项] '[定位符]指令'
==>定位符:
行号定位
正则定位
==>常用指令
p(print):打印行
d(delete):删除行
c(replace):替换行
s(substitution):替换关键词
=:打印行号
Print指令
[root@localhost ~]# sed -n '/IPADDR/p' /etc/sysconfig/network-scripts/ifcfg-eth0
#过滤网卡IP地址
[root@localhost ~]# free | sed -n '/Mem/p' #过滤内存信息
[root@localhost ~]# df -h | sed -n '/\/$/p'
#过滤磁盘根分区信息(根分区是以/结尾的分区)
[root@localhost ~]# sed -n '1p;3p;6p' /etc/passwd #显示第1、3、6行内容
[root@localhost ~]# sed -n '2!p' /etc/hosts #打印第2行以外的所有其他行内容
Delete指令(不使用-i选项,源文件不会被修改)
[root@localhost ~]# sed 'd' /etc/hosts
#删除/etc/hosts全文,没有定位条件等于匹配所有行
[root@localhost ~]# cat /etc/fstab > /tmp/fstab
[root@localhost ~]# sed '1,3d' /tmp/fstab #1到3行都删除
[root@localhost ~]# sed '/dev/!d' /tmp/fstab #不包含dev的行都删除
[root@localhost ~]# sed '/^#/d' /tmp/fstab #删除所有以#符号开头的行
[root@localhost ~]# sed '/^$/d' /tmp/fstab #删除空白行
Replace指令(不使用-i选项,源文件不会被修改)
[root@localhost ~]# sed 'c 123456' /tmp/fstab #所有行替换为123456
[root@localhost ~]# file=/etc/sysconfig/network-scripts/ifcfg-eth0
[root@localhost ~]# sed '/IPADDR/c IPADDR=1.1.1.1' $file #替换IP地址
[root@localhost ~]# sed '/127/c 127.0.0.1 localhost' /etc/hosts
[root@localhost ~]# sed '4c xxxx' /etc/shells
Substitution指令(不使用-i选项,源文件不会被修改)
[root@localhost ~]# vim test.txt
2046 2048 2046 2046
1001 2046 2999 1888
2046 2046 2046 2046
[root@localhost ~]# sed 's/2046/XXXX/' test.txt
[root@localhost ~]# sed 's/2046/XXXX/g' test.txt
[root@localhost ~]# sed 's/2046/XXXX/2' test.txt
[root@localhost ~]# sed 's/2046/(&)/g' test.txt
[root@localhost ~]# sed '2s/2046/XXXX/g' test.txt
[root@localhost ~]# sed '2s/2046//g' test.txt
[root@localhost ~]# sed -n '2s/2046/XXXX/p' test.txt
Substitution指令(替换符/可以用其他字符)
[root@localhost ~]# vim test.txt
2046 2048 2046 2046
1001 2046 2999 1888
2046 2046 2046 2046
[root@localhost ~]# sed 's#2046#XXXX#g' test.txt
[root@localhost ~]# sed 's,2046,XXXX,g' test.txt
[root@localhost ~]# sed 's!2046!XXXX!g' test.txt
[root@localhost ~]# sed 's2\20462XXXX2g' test.txt
[root@localhost ~]# sed 's2\20462\20492g' test.txt
正则符号()具有保留的功能
[root@localhost ~]# echo "hello the world" | sed -r 's/^(.)(.*)(.)$/\3\2\1/'
dello the worlh
=(打印行号)
[root@localhost ~]# sed -n '1=' /etc/passwd
[root@localhost ~]# sed -n '/root/=' /etc/passwd
[root@localhost ~]# sed -n '/bash$/=' /etc/passwd
[root@localhost ~]# sed -n '$=' /etc/passwd #统计行数
28
[root@localhost ~]# wc -l /etc/passwd #统计行数
28 /etc/passwd
==>文本块指令
i(insert):插入
a(append):追加
r(read):读取文件|导入文件内容
w(write):文件另存为|导出文件内容
Insert(插入,行前写入)
[root@localhost ~]# vim test.txt
2046 2048 2046 2046
1001 2046 2999 1888
2046 2046 2046 2046
[root@localhost ~]# sed '2i ABC_XYZ' test.txt
[root@localhost ~]# sed '3i ABC_XYZ' test.txt
[root@localhost ~]# sed '/2046/i ABC\nXYZ' test.txt
[root@localhost ~]# sed '/1888/i ABC\nXYZ' test.txt
Append(追加,行后写入)
[root@localhost ~]# vim test.txt
2046 2048 2046 2046
1001 2046 2999 1888
2046 2046 2046 2046
[root@localhost ~]# sed '2a ABC_XYZ' test.txt
[root@localhost ~]# sed '3a ABC_XYZ' test.txt
[root@localhost ~]# sed '/2046/a ABC\nXYZ' test.txt
[root@localhost ~]# sed '/1888/a ABC\nXYZ' test.txt
Read(将其他文件的内容导入)
[root@localhost ~]# vim test.txt
2046 2048 2046 2046
1001 2046 2999 1888
2046 2046 2046 2046
[root@localhost ~]# sed '2r /etc/hosts' test.txt
[root@localhost ~]# sed 'r /etc/hosts' test.txt
[root@localhost ~]# sed '/1888/r /etc/hosts' test.txt
Write(将文件内容导出另存到其他文件)
[root@localhost ~]# vim test.txt
2046 2048 2046 2046
1001 2046 2999 1888
2046 2046 2046 2046
[root@localhost ~]# sed 'w copy_test.txt' test.txt
#将test.txt文件的所有内容另存为一个新文件copy_test.txt
[root@localhost ~]# sed '/1888/w 1888.txt' test.txt
#将test.txt文件中所有包含1888的行另存为新文件1888.txt
[root@localhost ~]# sed '2,3w line.txt' test.txt
#将test.txt文件的2到3行另存为新文件line.txt
==>案例
点名器
[root@localhost ~]# vim /root/shell/day04/roll.sh
#!/bin/bash
#功能描述(Description):随机点名抽奖器.按Ctrl+C结束脚本.
name_file="name.txt"
line_file=$(sed -n '$=' $name_file)
while :
do
clear
tmp=$(sed -n "$[RANDOM%line_file+1]p" $name_file)
echo -e "\033[32m 随机点名器(按Ctrl+C停止):\033[0m"
echo -e "\033[32m#############################\033[0m"
echo -e "\033[32m# #\033[0m"
echo -e "\033[30m $tmp \033[0m"
echo -e "\033[32m# #\033[0m"
echo -e "\033[32m#############################\033[0m"
sleep 0.1
done
5.AWK数据过滤与数据分析
1)概述
awk编程语言/数据处理引擎
创造者:Aho、Weinberger、Kernighan
基于模式匹配检查输入文本,逐行处理并输出
通常用在Shell脚本中,获取指定的数据
单独用时,可对文本数据做统计
2)主要用法
格式1:前置命令 | awk [选项] '[条件]{指令}'
格式2:awk [选项] '[条件]{指令}' 文件.. ..
常用选项:-F可以指定分隔符,默认分隔符为(空格或Tab键)
awk内置变量
内置变量都有特殊含义,可直接使用
![]()
3)awk过滤(可单独使用,也可以同时一起使用)
在所有行前处理,BEGIN{ }
读入第一行文本之前执行
一般用来初始化操作
逐行处理,{ }
逐行读入文本执行相应的处理
是最常见的编辑指令块
在所有行后处理,END{ }
处理完最后一行文本之后执行
一般用来输出处理结果
4)awk流程控制
单分支if判断
[root@localhost ~]# awk -F: '{if($3>=1000){i++}} END{print i}' /etc/passwd
[root@localhost ~]# awk -F: '{if($1=="root"){print $1,$3}}' /etc/passwd
[root@localhost ~]# uptime | awk '{ if($NF>0.01){print "CPUload:"$NF}}'
双分支if判断
[root@localhost ~]# awk -F: '{ if($3>=1000){i++} else{j++} } \
END{print "普通用户:" i, "系统用户:" j }' /etc/passwd
[root@localhost ~]# ls -l /etc | awk \
'{
if($1~/^-/) {x++} else {y++} \
} \
END {print "普通文件个数:"x,"目录个数:"y}'
多分支if判断
[root@localhost ~]# ls -l /etc | awk \
'{
if($1~/^-/) {x++} else if ($1~/^d/) {y++} else{z++} \
} \
END {print "普通文件个数:"x,"目录个数:"y, "其他个数:"z}'
for循环
[root@localhost ~]# awk 'BEGIN{ for (i=1;i<=5;i++) {print i}}'
[root@localhost ~]# awk 'BEGIN{ for (i=5;i>=1;i--) {print i}}'
5)awk数组
定义数组
格式:数组名[下标]=元素值
调用数组
格式:数组名[下标]
遍历数组
格式:for(变量名 in 数组名) {print 数组名[变量]}
6)TCP连接状态
三次握手
![]()
四次断开
![]()
7)ss命令
![]()