Awk和Shell
awk
格式
awk [选项参数] 'script' var=value file(s)
- 基本语法
- $0 代表整个文本行
- $1 代表文本行中的第 1 个数据字段
- printf 打印输出
- 默认每行按空格或TAB分割,使用$n来获取段号
段连接符OFS
awk '{OFS="#"}{print $1,$2,$3}' test_awk.txt
指定分隔符 -F
awk -F ":" '{print $1}' test_awk2.txt
内容匹配
格式'/这里写具体的正则表达式/'
- 正则规则
- 1、^linux 以linux开头的行
- 2、$php 以php结尾的行
- 3、. 匹配任意单字符
- 4、.+ 匹配任意多个字符
- 5、 .* 匹配0个或多个字符(可有可无)
- 6、 [0-9a-z] 匹配中括号内任意一个字符
- 7、 (linux)+ 出现多次Linux单词
- 8、 (web){2} web出现两次以上
- 9、\ 屏蔽转义
- 匹配到aaa或者ddd,就打印全部内容
awk -F ':' '/aaa|ddd/ {print $0}' test_awk2.txt
段内容判断
- 支持赋值,条件表达式,关系运算符等
段之间比较
awk -F ':' '$3<$4 {print $0}' test_awk2.txt
NR行号和NF段数
- 概念
- NF段数
- NR行号从1开始
- nl命令在linux系统中用来计算文件中行号
nl test_awk2.txt | head -2
- 从test_awk2.txt前3行,把第1段内容替换为test,指定分隔符为|,显示行号
awk -F ':' '{OFS="|"} NR<=3 && $1="test" {print NR, $0}' test_awk2.txt
分段求和
- 格式
- BEGIN{} {} END{}
- BEGIN{}在读取数据之前做的事情, 可以理解为: 前.
- {} 在读取过程中做的事情, 可以理解为: 中.
- END{} 在读取数据之后做的事情, 可以理解为: 后.
- 对test_awk2.txt中的第2段求和
awk -F ':' 'BEGING{}{total=total+$2}END{print total}' test_awk2.txt
awk -F ':' 'BEGIN{}{total=total+$2}END{print total}' test_awk2.txt
综合案例
- 统计当前目录所有文本文件的大小
awk 'BEGIN{}{total=total+$5} END{print(total)}'
- 打印99乘法表
awk 'BEGIN{ for(i=1;i<=9;i++){ for(j=1;j<=i;j++){ printf("%dx%d=%d%s", i, j, i*j, "\t" ) } printf("\n") } }'
- 求总成绩
文本文件
Marry 2143 78 84 77
Jack 2321 66 78 45
Tom 2122 48 77 71
Mike 2537 87 97 95
Bob 2415 40 57 62
脚本文件
#!/bin/awk -f
#运行前
BEGIN {
math = 0
english = 0
computer = 0
printf "NAME NO. MATH ENGLISH COMPUTER TOTAL\n"
printf "---------------------------------------------\n"
}
#运行中
{
math+=$3
english+=$4
computer+=$5
printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5
}
#运行后
END {
printf "---------------------------------------------\n"
printf " TOTAL:%10d %8d %8d \n", math, english, computer
printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR
}
shell编程
基本介绍
- shell脚本执行方式Shell 是一个用 C 语言编写的程序,通过 Shell 用户可以访问操作系统内核服务。
- 查看系统安装
shellcat /etc/shells
- 查看Linux系统默认的SHELL解释器的
echo $SHELL
格式
#!/bin/bash
4种运行方式
- sh执行
- 工作目录执行
- 绝对路径执行
- source hello.sh
变量
- 用户变量
- 环境变量
- 特殊变量
- $#命令行参数的个数
- $n 表示第n个参数
- $0 当前程序的名称
- $? 前一个命令或许或函数的返回码
- $*以“参数1 参数2 。。。”形式保存所有参数
- $@ 以“参数1”“参数2”。。。形式保存所有参数
- $$ 本程序的(进程ID号)PID
- $! 上一个命令的PID
字符串
- 优先使用双引号
- 拼接字符串
wenhou_1="你好,$yourname ."
wenhou_2="你好,"$yourname" ."
wenhou_3="你好,\"$yourname\" ."
- 获取字符串长度
#!/bin/bash
string="jobs"
echo ${string} # 输出结果: jobs
echo ${#string} # 输出结果: 4
- 提取子字符串
#!/bin/bash
string="敢于亮剑决不后退"
echo ${string:2:2} # 输出结果为: 亮剑
- 查找字符串(记得有漂号)
#!/bin/bash
string="i am a boy"
echo `expr index "$string" am`
算术运算符
- 支持包括:算术、关系、布尔、字符串等运算符
流程控制
- 数字语句判断
- -eq 检测两个数是否相等,相等返回 true。
- -ne检测两个数是否不相等,不相等返回 true。
- gt检测左边的数是否大于右边的,如果是,则返回 true。
- lt检测左边的数是否小于右边的,如果是,则返回 true。
- -ge检测左边的数是否大于等于右边的,如果是,则返回 true。
- -le检测左边的数是否小于等于右边的,如果是,则返回 true。
- 字符串语句判断
- n STRING 字符串长度不为零
- z STRING 字符串长度为0
- = 判断两个字符串是否一样
- !=判断两个字符串是否不一样
- 文件语句判断
- f 存在且是普通文件
- -d 存在且是目录
- h 存在且是符号链接
- e 文件存在
- –r 文件存在并且可读
- –w 文件存在并且可写
- –x 文件存在并且可执行
- test命令:可以代替[]
- 为0表示为真,为1表示为假
- let命令:执行一个或多个表达式
- if语句格式
if condition //条件, 条件要用 [] 包裹.
then
command1 //符合条件后, 就会执行这里的内容
command2
...
commandN
fi
- if else 语法格式
if condition //条件, 用[]包裹
then
command1 //符合条件后, 执行的内容
command2
...
commandN
else
command //不符合条件后, 执行的内容.
fi
- if else-if else
if condition1 //条件1
then
command1 //满足条件1后, 执行的内容
elif condition2 //条件2
then
command2 //满足条件2后, 执行的内容
else
commandN //所有条件都不满足, 则执行这里.
fi
- 第一种for循环
for 变量 in 值1 值2 值3…
do
程序
done
- 第二种for循环
for ((初始值;循环控制条件;变量变化))
do
程序
done
- while循环
while 条件
do
程序
done
- 死循环
# 方式1
while :
# 方式2
while true
# 方式3
for ((;;))
- case判断语句
case 值 in
模式1)
command1
command2
...
commandN
;;
模式2)
command1
command2
...
commandN
;;
esac
- 跳出循环break和continue操作
函数
- 语法格式
[ function ] funname(){
action;
[return int;]
}
- 格式解释
- 可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
- 参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255)
- 注意事项
- 函数返回值在调用该函数后通过 $? 来获得。
- 所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。 调用函数仅使用其函数名即可。
- 函数的返回值只能是0-255区间的数据, 否则返回的内容可能不是我们想要的结果. 一般定义一个函数, 是为了实现特殊的功能, 当这个功能执行完成后, 返回一个状态信息. 0成功, 1失败等, 我们根据这个信息再来做其他的操作即可.
- $? 严格意义来讲并不是获取返回值的, 而是获取上一个的执行后状态码信息(0-255之间)默认情况下如果状态码为0 表示成功执行, 如果为其他值, 则表示执行有问题
- 如何具体接收方法返回值的问题
- 在方法外定义变量
- 用输出语句输出,在方法外用变量接收该值
- 有参数的函数操作
- $1表示第一个参数,以此类推
数组
- 定义数组
my_array=(A B "C" D) array_name[0]=value0 array_name[1]=value1 array_name[2]=value2
- 读取数组
echo "第一个元素为: ${my_array[0]}"
- 获取数组所有元素
echo "数组的全部元素为: ${my_array[*]}" echo "数组的全部元素为: ${my_array[@]}"
- 获取数组长度
echo "数组元素个数为: ${#my_array[*]}" echo "数组元素个数为: ${#my_array[@]}"
- 遍历数组:结合2中for循环
select语句
- 概念
- 擅长于交互式场合。用户可以从一组不同的值中进行选择.
格式PS3= //界面提示符select var in ... ; do commond done .... now $var can be used ...
- 注意事项:break 命令退出循环,或exit 命令终止脚本
加载其它变量
- 格式1:
. filename
- 格式2:
source filename
(推荐使用)
综合案例
- 1.猜数字小游戏
#!/bin/bash
#生成100以内的随机数 提示用户猜测 猜对为止
#random 系统自带,值为0-32767任意数
#随机数1-100
num=$[RANDOM%100+1]
#read 提示用户猜数字
#if判断
while :
do
read -p "计算机生成了一个 1‐100 的随机数,你猜: " cai
if [ $cai -eq $num ]
then
echo "恭喜,猜对了"
exit
elif [ $cai -gt $num ]
then
echo "不巧,猜大了"
else
echo "不巧,猜小了"
fi
done
- 2.数据库定时备份
#!/bin/bash
#完成数据库的定时备份
#备份的路径
BACKUP=/export/data/db
#当前时间作为文件名
DATETIME=$(date +%Y_%m_%d_%H%M%S)
#可以通过输出变量来调试
echo $DATETIME
#使用变量的时候,也可以用{}花括号的方式把变量名包起来,如下:
echo ${DATETIME}
echo "---------------------开始备份数据库---------------------"
echo "---------------------备份的路径是$BACKUP/$DATETIME.tar.gz---------------------"
#主机ip地址
HOST=192.168.88.100
#数据库用户名
DB_USER=root
#数据库密码
DB_PWD=123456
#数据库名
DATABASE=test_shop
#创建备份路径
#如果备份的文件夹路径存在的话,就直接使用,否则就创建
[ ! -d "${BACKUP}/${DATETIME}" ] && mkdir -p "${BACKUP}/${DATETIME}"
#执行mysql的备份数据库的指令
mysqldump -u${DB_USER} -p${DB_PWD} --host=${HOST} ${DATABASE} | gzip > ${BACKUP}/${DATETIME}/${DATETIME}.sql.gz
#打包备份文件
cd ${BACKUP}
tar -czvf ${DATETIME}.tar.gz ${DATETIME}
#删除临时目录
rm -rf ${BACKUP}/${DATETIME}
#删除10天前的备份文件
find ${BACKUP} -mtime +10 -name "*.tar.gz" -exec rm -rf {} \;
echo "-------------------------备份成功-------------------------"
小技巧总结
给变量赋值的特殊写法
a=`Linux命令`
a=$(Linux命令)
# 这两个命令的执行结果是一样的, 都是把Linux命令的执行结果给变量
关于数字的运算
$((10 + 20))
$[10 + 20]
`expr 10 + 20 `
关于for, while的条件
如果是 for(()) 或者 while (()) 这种方式, 不用通过$引入变量, 可以直接用.
如果是 for[] 或者 while[]这种方式, 必须通过$引入变量, 才可以继续使用.
Awk和Shell
https://jface001.github.io/2021/06/10/Awk和Shell/