Shell 总结
变量替换和测试 变量替换
变量测试
字符串处理 计算字符串长度 方法一
方法二
子串 获取子串在字符串中的索引位置
1 expr index $string $substring
抽取子串
总结 计算字符串长度
1 2 3 var1="This is a app" len=${#$var1} len=`expr length "$var1 " `
子串索引
1 2 var1="quicstart is a app" ind=`expr index "$var1 " start`
子串长度
1 2 var1="quicstart is a app" ind=`expr match "$$var1 " app`
抽取字符串中的子串
1 2 3 4 5 var1="quicstart is a app" substr1=${var1:10} substr2=${var1:10:6} substr1=${var1:-5} substr1=${var1:-10:4}
expr 索引1开始,${string:position}从0开始 实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 #! /bin/bash string="Bigdata process framework is Hadoop,Hadoop is an open source project" function print_tips{ echo "***********************" echo "(1) 打印string长度" echo "(2) 删除字符串中所有Hadoop" echo "(3) 替换第一个Hadoop为Mapreduce" echo "(4) 替换全部Hadoop为Mapreduce" echo "**********************" } function len_of_string{ echo "${#string} " } function del_hadoop{ echo "${string/Hadoop/} " } function rep_hadoop_mapreduce_first{ echo "${string/Hadoop/Mapreduce} " } function rep_hadoop_mapreduce_all{ echo "${string//Hadoop/Mapreduce} " } while true do echo "【string=$string 】" echo print_tips read -p "Pls input your choice(1|2|3|4|q|Q):" choice case $choice in 1) len_of_string ;; 2) del_hadoop ;; 3) rep_hadoop_mapreduce_first ;; 4) rep_hadoop_mapreduce_all ;; q|Q) exit ;; *) echo "Error,input only in {1|2|3|4|q|Q}" ;; esac done
命令替换 语法格式
例题 获取系统所有用户并输出
1 2 cat /etc/passwd | cut -d “:” -^C cat /etc/passwd | cut -d “:” -f 1
1 2 3 4 5 6 7 #! /bin/bash nginx_process_num=$(ps -ef | grep nginx | grep -v grep | wc -l) if [ $nginx_process_num -eq 0 ];then systemctl start nginx fi
总结 \
`和
$()`
``和$()是等价的,但初学推荐$() $(())用于进行整数运算,包括加减乘除 $(((100 + 30) / 12)) 有类型变量 declare 和 typeset 命令 两者关系:两者等价,都是用来定义变量类型
declare参数表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 declare -i ab ab=56 echo $ab 56 declare -i ef ef=1 echo $ef 1 ef="wer" echo $ef 0 declare +i ef ef="wer" echo $ef wer declare -r ab ab=88 echo $ab 56 declare -a cd ='([0]="a" [1]="b" [2]="c")' echo ${cd[1]} b echo ${cd[@]} a b c
declare -x
声明为环境变量,可在脚本中直接使用取消声明的变量 1 2 3 4 declare +rdeclare +ideclare +adeclare +X
数学运算 语法格式
expr操作符对照表
例子
Bash运算之bc bc 操作
1 2 3 scale=2 echo “20+22” | bcecho “scale=3;23+33” | bc
函数 函数定义和使用 Linux Shell中的函数和大多数编程语言中的函数一样,将相似的任务或代码封装到函数中,供其他地方调用
语法一
1 2 3 4 5 6 7 name (){ command1 command2 .... commandn }
语法二
1 2 3 4 5 6 7 function name{ command1 command2 .... commandn }
如何调用 直接使用函数名调用,可以将其想象成 Shell 中的一条命令 函数内部可以直接使用函数 $1,$2…$n 调用函数:function_name $1 $2 例题 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #!/bin/bash this_pid=$$ while true do ps -eff | grep nginx | grep -v grep | grep -v $this_pid &> /dev/null if [ $? -eq 0];then echo "Nignx is running well" sleepp 3 else systemctl start nginx echo "Nginx is down,start it.." fi done
判断进程
1 2 netstat -tnlp | grep :80 curl localhost/index.html
向函数传递参数 shell传参 1 2 3 4 5 function name{ echo "Hello $1 " echo "Hello $2 " }
函数返回值 return echo reutrn 返回值 只能返回1-255的整数 通常智能用来供其他地方调用获取状态,因此仅返回0(成功),1(失败) echo 返回值 可以返回任何字符串结果 通常用于返回数据,如一个字符串值或列表值 局部变量全局变量 全局变量 不做特殊处理,shell 中变量为全局变量 大型脚本程序慎用 局部变量 定义时,使用local关键字 函数内外如果存在同名变量,册函数内部变量覆盖外部变量 函数库 经常使用的重复代码封装成函数文件 一般不直接执行,而是由其他脚本调用 实例
库文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 function add{ echo "`expr $1 + $2 `" } function reduce{ echo "`expr $1 - $2 `" } function multiple{ echo "`expr $1 \* $2 `" } function diveid{ echo "`expr $1 / $2 `" } function sys_load{ echo "Memory Info" free -m echo echo "Disk Usage" echo df -h }
1 2 3 4 5 6 7 #!/bin/bash . /home/vitan/workplace/Shell/learn/function/base_function add 122 3 reduce 9 3 multiple 22 11 diveid 12 3 sys_load
注意事项 库文件名的后缀是任意的,但一般用 .lib
库文件通常没有可执行权限 库文件无需和脚本在同级目录,只需在脚本中引时指定 第一行一般使用 #!/bin/bash/echo
,输出警告信息,避免用户执行 文件查找之find命令 find [路径][选项][操作]
实例 查找 /etc 目录下 conf 结尾的文件 查找当前目录下文件名为 aa 的文件,不区分大小写 查找文件属主为 hdfs 的所有文件 查找文件属组为 yarn 的所有文件 选项 -type f 文件 find . -type f d 目录 dind . -type d c 字符设备文件 dind . -type c b 块设备文件 dind . -type b l 链接文件 dind . -type l p 管道文件 dind . -type p -size -n 大小小于n的文件 +n 大小大于n的文件 n 大小等于n的文件 1 2 3 4 find /etc -size -10000c find /etc -size +1M
-mtime-n n天以内修改的文件 +n n天以外修改的文件 n 正好n天修改的文件 1 2 3 4 find /etc -mtime -5 -name '*.conf' find /etc -mtime +10 -user root
-mmin 1 2 3 4 find /etc -mmin +30 find /etc -mmin -3o -type d
-mindepth n -maxdepth n 1 2 3 find /etc -maxdepth 3 -name '*.conf' find ./etc -type f -name '.*conf' -size +10k -maxdepth 2 find . -type f -nogroup
-perm
-prune
通常和-path一起用,用于将特定目录排除在搜索条件之外 1 2 3 4 5 6 7 8 find . -path ./etc -prune -o -type f find . -path ./etc -prune -o -path ./opt -prune -o -type f find . -path ./etc -prune -o -path ./opt -prune -o -type -f -a -user hdfs find . -path ./etc -prune -o -path ./opt -prune -o -type -f -a -user hdfs -a -size +2M
-newer file1 操作
1 2 3 4 5 find ./etc -type -f -name '*.conf' -size +10k -exec rm -rf {} \; find /var/log/ -name '*.log' -mtime +7 -exec rm -rf {} \; find /etc -size +10k -type -f -name '*.conf' -exec cp {} /root/conf/ \;
-print 打印输出 -exec 对搜索的文件执行特定的操作 -ok 和exec功能一样,但每次操作都会给用户提示 逻辑运算符
find locate whereis和 which 总结及使用场景分析 locate 文件查找命令,所属软件包mlocate 不同于find命令是在整块磁盘中搜索,locate在数据库文件中查找 find默认全部匹配,locate默认部分匹配 updatedb命令用于更新/var/lib/mlocate/mlocate.db 所使用配置文件/etc/update.conf 该命令在后台cron计划任务定期执行 whereis选项和含义 -b 只返回二进制文件 -m 只返回帮助文档文件 -s 只返回源码文件 which 各命令使用场景推荐
grep和egrep grep 语法
grep [option] [pattern] [file1,file2…] command | grep [option] [pattern] grep参数
grep -E “python | PYTHON” file egrep egrep语法
1 egrep(选项)(查找模式)(文件名1,文件名2,……)
sed sed(Stream Editor),流编辑器,对标准输出或文件逐行进行处理
语法 stdot | sed [option] “pattern command” sed [option] “pattern command” file 选项
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 sed ‘p’ sed.tet sed -n‘p’ sed.tet sed ‘/python/p’sed.txt sed -n‘/python/p’sed.txt sed -n -e ‘/python/p’ -e ‘/PYTHON/p’ sed.txt Vim edit.sed /python/p Sed -n -f edit.sed sed.txt Sed -n -r‘/python|PYTHON/p’ sed.txt sed -n ‘s/love/like/g’ sed.txt sed -i‘s/love/like/g’ sed.txt
sed 的 pattern 详解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 sed -n "17p" file sed -n "10,20p" file sed -n "10,+5p" file sed -n "/^root/p" file sed -n "/^root/,/^ftp/p" file sed -n "4,/^hdfs/p" file sed -n "/root/,10p" file
sed 中的编辑命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 sed -i‘1d/ sed.txt # 删除第一行 sed -i ‘1,3d’sed.txt # 删除1-3行 sed -i ‘/\/sbin\/nologin/d’passwd # 把不可登录的账号删除 sed -i ‘/^mail,/^ftp/d’pssswd #mail到ftp 文本追加 sed -i ‘/\/bin\/bash/a This is user which can login to system’pssswd # 行后追加 sed -i ‘/^hdfs/,/&yarn/i AAAAAA’ pssswd # 行间追加 sed -i ‘/root/r list’ passwd #把list内容追加root行后面 sed -n‘/\/bin\/bash/w /tmp/user_login.txt’passwd #保存 sed -i ‘s/\/bin\/bash/\/BIN\/BASH/g’passwd # 小写的替换为大写 sed -i ‘a/root/ROOT/’passwd # 替换第一个root为大写 sed -i ‘a/root/ROOT/2’passwd # 替换前两个个root为大写 sed -i ‘s/hadoop/HADOOP/ig’str.txt #不区分大小写 sed -n ‘/\/sbin\/nologin/=’passwd # 查看行号,不显示内容 sed -i ‘s/had..p/hadoops/g’ sed.txt #.任意一个字符 sed -i ‘s/had..p/&s/g’ sed.txt #hadXXp后面加s,反向引用 sed -i ‘s\/(had..ps\)\/1O/g’ sed.txt #后加O sed -i ‘s/\(had\)...../\1doop/g’sed.txt # had后面替换
反向引用 &和\1 引用模式匹配到的整个串 1 2 3 sed "s/1..e/&r/g" file sed "s/\(1...e\)/\1r/g" file
上面两种方法实现一样的功能,分别使用&和\1代表搜寻到的整个字符串 区别在于&只能表示匹配到的完整字符串,只能引用整个字符串,而\1可以使用()对匹配到的 要替换匹配的字符串的一部分,name必须使用\1,不能使用& sed 引用变量 匹配模式中存在变量,则建议使用双引号 sed中需要引入自定义变量时,如外面使用单引号,则自定义变量必须使用单引号 用 sed 查询特定内容 查询命令
实例
1 2 3 4 5 6 7 8 9 sed -n "20p" /etc/passwd sed -n "8,15p" /etc/passwd sed -n "8,+5p" /etc/passwd sed -n '/^hdfs/p' /etc/passwd sed -n '^root/,/^hdfs/p' /etc/passwd sed -n '8,/\sbin\/nologin/p' /etc/passwd sed -n '\bin\/bash/,5p' /etc/passwd
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #!/bin/bash FILE_NAME=/root/my.cnf function get_all_segments{ echo "`sed -n '/\[.*\]/p' $FILE_NAME | sed -e 's/\[//g' -e 's/\]//g'`" } function count_items_in_segment{ items=`sed -n '/\[' $1 '\]/,/\[.*\]/p' $FILE_NAME | grep -v "^#" | grep -v ^$ | grep -v "\[.*\]" ` index=0 for item in $items do index=`expr $index +1` done echo $index } number=0 for segment in `get_all_segments`do num=`expr $number + 1` items_count=`coubt_items_in_segment $segment ` echo "$number : $segment $items_count " done
sed 删除特定内容
1 2 3 4 5 6 7 8 sed -i '15d' passwd sed -i '8,14d' passwd sed -i '/\sbin\/nologin/d' passwd sed -i '/^mail/,/^yarn/d' passwd sed -i '/\sbin\/nologin/,13d' passwd sed -i '5,/^ftp/d' passwd sed -i '/^yarn/,$' /etc/passwd
删除配置文件中所有的注释行和空行 在配置文件中所有不以#开头的行前面加×符合,主要以#开头的行不添加 1 2 3 sed -i ‘/^#/d;/^$/d’ nginx.conf sed -i ‘/[:blank:]*#/d’ nginx.conf sed -i ‘/^[^#]/\*&/g’nginx.conf
sed 修改文件内容
实例
1 2 3 4 5 6 7 8 9 10 11 12 sed -i '1s/root/ROOT/' passwd sed -i '5,10s/\/sbin\/nologin/\bin\/bash/g' passed sed -i '/\sbin\/nologin/s/login/LOGIN/g' passwd sed -i '/^root/,15s/nologin/SPARK/g' passwd sed -i '15,/^yarn/s/bin/BIN/g' passwd sed -i 's/[0-9]*//g' file.txt
sed 追加文本内容 a1 2 3 4 5 6 sed -i '10a Add lind behind' passwd sed -i '10,20a Test line behind' passws sed -i '/\bin\/bash/a insert line for /bin/bash behind' passws
i1 2 3 4 sed -i 'yarn/i Add lind behind' passwd sed -i 'i insert line before every line' passwd
r1 2 3 4 5 6 sed -i '20r /etc/fstab' passwd sed -i '/\bin\/bash/r /etc/inittab' passwd sed -i /^ftp/,18r /etc.vconsole.conf’ pssswd
w1 2 3 4 sed -i '/\bin\/bash/w /tmp/sed.txt' passwd sed -i '10,/^hsfs/w /tmp/sed-1.txt' passwd
awk awk 的工作模式 awk 为一个文本处理工具,通常用于处理数据并产生结果报告。 命名是由三个创始人姓氏首字母组成 语法 1 2 3 awk 'BEGIN{}pattern{commands}END{}' file_name standard outpu | awk 'BEGIN{}pattern{commands}END{}' file_name
awk 内置变量 内置变量对照表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 awk '{print $0}END{}' /etc/ passwd awk 'BEGIN{FS=":"}{print $1}' /etc/ passwd awk '{print $1' list.txt awk '{print NF}' list.txt awk '{print NR}' list.txt /etc/ passwd awk '{print FNR}' list.txt /etc/ passwd awk 'BEGIN{FS="|"}{print $2}' list.txt awk 'BEGIN{FS="|";RS="--"}{print $2}' list.txt awk 'BEGIN{FS="|";RS="--";ORS="&"}{print $2}' list.txt awk 'BEGIN{FS="|";RS="--";ORS="&";OFS=":"}{print $2,$3}' list.txt awk '{print FILENAME}' list.txt awk '{print ARGC}' list.txt awk 'BEGIN{FS=":"}{print $NF}' /etc/ passwd
awk 格式化输出 printf(默认不带分隔符) 语法
修饰符
实例
1 2 3 4 5 6 7 8 9 10 11 12 13 awk 'BEGIN{FS=":"}{printf $1}' /etc/ passwd awk 'BEGIN{FS=":"}{printf "%s\n",$1}' /etc/ passwd awk 'BEGIN{FS=":"}{printf "%s%s\n",$1,$7}' /etc/ passwd awk 'BEGIN{FS=":"}{printf "%20s %20s\n",$1,$7}' /etc/ passwd awk 'BEGIN{FS=":"}{printf "%-20s %-20s\n",$1,$7}' /etc/ passwd
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 awk 'BEGIN{FS=":"}{printf "%s\n",$7}' /etc/ passwd awk 'BEGIN{FS=":"} {printf "%d\n",$3}' /etc/ passwd awk 'BEGIN{FS=":"} {printf "%o.3f\n",$3}' /etc/ passwd awk 'BEGIN{FS=":"} {printf "%x\n",$3}' /etc/ passwd awk 'BEGIN{FS=":"} {printf "%o\n",$3}' /etc/ passwd awk 'BEGIN{FS=":"} {printf "%e\n",$3}' /etc/ passwd
awk模式匹配的两种用法 RegExp 含义:按正则表达式匹配 关系运算 含义:按关系运算匹配 实例
1 2 3 4 5 awk 'BEGIN{FS=":"}/root/{print $0}' /etc/ passwd awk 'BEGIN{FS=":"}/^yarn/{print $0}' /etc/ passwd
(运算符)关系运算
关系运算符:<,><=,>=,==,!=,~(匹配正则表达式),!~ 1 2 3 4 5 6 7 8 9 10 11 awk 'BEGIN{FS=":"}$3<50{print $0}' /etc/ pssswd awk 'BEGIN{FS=":"}$7=="/bin/bash"{print $0}' /etc/ pssswd awk 'BEGIN{FS=":"}$7!="/bin/bash"{print $0}' /etc/ pssswd awk 'BEGIN{FS=":"}$3~/[0-9]{3,}/{print $0}' /etc/ passwd awk 'BEGIN{FS=":"}$0~/\sbin\/nologin/{print $0}' /etc/ passwd
1 2 3 4 5 6 7 awk 'BEGIN{FS=":"}$1=="hdfs" || $1=="yarn" {print $0}' /etc/ passwd awk 'BEGIN{FS=":"}$3<50 && $4>50 {print $0}' /etc/ passwd awk 'BEGIN{FS=":"}$3<50 && $7~/\bin\/bash/ {print $0}' /etc/ passwd
awk 动作中的表达式用法 算术运算符
运算符 含义 + 加 - 减 * 乘 / 除 % 模 ^或** 乘方 ++X 再返回X变量之前,X变量加1 X++ 再返回X变量之后,X变量加1
1 2 3 4 5 6 7 8 9 10 11 awk 'BEGIN{var=20;var1="hello";print var,var1}' awk 'BEGIN{num1=20;num2+=num1;print num2,num2}' awk 'BEGIN{num1=20;num2+=num1;print num2+num2}' awk 'BEGIN{num1=20;num2=30;printf "%0.2f\n",num1/num2}' awk 'BEGIN{x=2;y=x++;print x,y}' awk 'BEGIN{x=2;y=x--;print x,y}'
1 2 3 4 5 6 7 awk '/^$/{sumx=0;sum++}END{print sum}' /etc/ services awk '{total=S2+$3+$5+$5;AVG=total/4;printf "%-8s,%-5d%-5d%-5d%-8d%0.2f\n",$1,$2,$3,$4.$5,AVG}' stu.txt awk 'BEGIN{printf "%-8s%-8s%-8s%-8s%-8s%s\n","姓名","语文","数学","英语","物理","平均分"}{total=$2+$3+$4+$5;AVG=total/4;printf "%-8s%-8d%-8d%-8d%-8d%0.2f\n",$1,$2,$3,$4.$5,AVG}' stu.txt
awk 动作中的条件及循环语句 1 2 3 4 5 6 if (条件表达式) 动作1 else if (条件表达式) 动作2 else 动作3
1 2 3 4 5 6 7 8 9 10 awk 'BEFIN{FS=":"}{if($3>50 && $3<100>) print $0}' /etc/ passwd awk 'BEFIN{FS=":"}{if($3>50 || $3<100>) print $0}' /etc/ passwd awk 'BEGIN{FS=":"}{if($3<50) printf "%-10s%-5d\n","小于50的UID:",$3}' /etc/ passwd awk 'BEGIN{FS=":"}{if($3<50) printf "%-10s%-10s%-5d\n","小于50的UID:",$1,$3}' /etc/ passwd awk 'BEGIN{FS=":"}{if($3<50) printf "%-10s%-10s%-5d\n","小于50的UID:",$1,$3}' /etc/ passwd
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 BEGIN { FS=":" } { f($3 <50 ) { printf "%-30s%-20s%-5d\n" ,"小于50的UID" ,$1 ,$3 } else if ($3 >50 && $3 <100 ) { printf "%-30s%-20s%-5d\n" ,"大于50且小于100的UID" ,$1 ,$3 } else { printf "%-30s%-20s%-5d\n" ,"大于100的UID" ,$1 ,$3 } }
1 awk -f scripts.awk /etc/ passed
do while 循环 1 2 3 4 do while do 动作 while (条件表达式)
for 循环 1 2 for (初始化计数器;测试计数器;计数器变更) 动作
实例
while 1 2 3 4 5 6 7 BEGIN { while (i<=100 ) { sum+=1 } print sum }
1 2 3 4 5 6 7 BEGIN { for (i0;i<=100 ;i++) { sum+=1 } print sum }
do while 1 2 3 4 5 6 7 8 BEGIN { do { sum+=1 i++ }while (i<=100 ) print sum }
awk -f do_while.awk
计算每个同学平均分,仅显示大于90
student.awk 1 2 3 4 5 6 7 8 9 10 11 BEGIN { printf "%-10s%-10s%-10s%-10s%-10s%-10s\n" ,"Name" ,"Chinese" ,"English" ,"Math" ,"Physical" ,"Average" } { total=$2 +$3 +$4 +$5 avg=total/4 if (avg>90 ) { printf "%-10s%-10d%-10d%-10d%-10d%-0.2f\n" ,$1 ,$2 ,$3 ,$4 ,$5 ,avg } }
student.awk 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 BEGIN { printf "%-10s%-10s%-10s%-10s%-10s%-10s\n" ,"Name" ,"Chinese" ,"English" ,"Math" ,"Physical" ,"Average" } { total=$2 +$3 +$4 +$5 avg=total/4 if (avg>90 ) { printf "%-10s%-10d%-10d%-10d%-10d%-0.2f\n" ,$1 ,$2 ,$3 ,$4 ,$5 ,avg score_chinese+=$2 score_english+=$3 score_math+=$4 score_physical+=$5 } } END { printf "%-10s%-10d%-10d%-10d%-10d\n" ,"" ,score_chinese,score_english,score_math,score_physical }
awk 中的字符串函数 字符串函数对照表
例子
以:为分隔符,返回文件中每行中的字段长度 1.awk 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 BEGIN { FS=":" } { i=1 while (i<=NF) { if (i==NF) printf "%d" ,length($i ) else printf "%d:" ,length($i ) i++ } print "" }
搜索字符串”I have a dream”中出现”ea”子串的位置 1 2 3 4 5 awk 'BEGIN{str="I have a dream";location=index(str,"ea");print location}' awk 'BEGIN{str="I have a dream";location=match(str,"ea");print location}'
将字符串”Hadoop is a bigdata Framework”全部转为小写 1 awk 'BEGIN{str="Hadoop is a bigdata Framework";print tolower(str)}'
上一题转为大写 1 awk 'BEGIN{str="Hadoop is a bigdata Framework";print toupper(str)}'
将字符串”Hadoop Kafka Spark Storm”按空格为分隔符,分割每一部分保存到数组arr中 1 2 3 4 awk 'BEGIN{str="Hadoop Kafka Spark Storm";split(str,arr," ");print arr[0]}' awk 'BEGIN{str="Hadoop Kafka Spark Storm";split(str,arr," ");for(a in arr) print arr[a]}'
搜索字符串”Tranction 2345 start:select * from master”第一个数字出现的位置 1 awk 'BEGIN{str="Tranction 2345 start:select * from master";location=match(str,/[0-9]/);print location}'
截图字符串”transaction start”的子串,条件从第4个字符开始,截取5为 1 awk 'BEGIN{str="transaction start";print substr(str,4,5)}'
替换”Tranction 243 start,Event ID:9002”中第一个匹配到的数字为$符号 1 2 3 4 awk 'BEGIN{str="Tranction 243 start,Event ID:9002";count=sub(/[0-9]+/,"$",str);print count,str}' awk 'BEGIN{str="Tranction 243 start,Event ID:9002";count=gsub(/[0-9]+/,"$",str);print count,str}'
awk中的常用选项 选项 解释 -v 参数传递 -f 指定脚本文件 -F 指定分隔符 -V 查看awk的版本号
实例
终端中 1 2 3 num1=20 var="Hello World" awk -v num2="$num1 " -v var1="$var " 'BEGIN{print num2,var1}'
1 awk -f student.awk /etc/passws
1 2 3 4 awk -F ":" '{print $7}' /etc/passwd awk -F : '{print $7}' /etc/passwd awk 'BEGIN{FS=":"}{print $7}' /etc/passwd
Shell 数组的用法 array=(“Mike”,”Bell”,”Hellen”) 解释 代码 打印元素 echo ${井array[2]} 打印元素个数 echo ${井array[@]} / echo ${井array[*]} 打印元素长度 echo ${井array[3]} 给元素赋值 array[3]=”LI” 删除元素 unset array[2];unset array 分片访问 echo ${井array[@]:1:3} 元素内容替换 ${array[@]/e/E} #只替换第一个e;${array[@]//e/E}替换全部e
1 2 3 4 for a in arraydo echo $a done
awk 数组用法 awk中使用数组时,不仅可以使用数字作为数组下标,也可以使用字符串作为数组下标 统计主机上所有TCP连接状态,按照每个TCP状态分类 1 netstat -an | grep tcp | awk '{arrary[$6]++}END{for(a in arrary) print a,arrary[a]}'
计算横向数总和,计算纵向数据总和 数据 1 2 3 4 5 6 Allen 80 90 96 98 Mike 93 98 92 91 Zhang 78 76 87 92 Jerry 86 89 68 92 Han 85 95 75 90 Li 78 88 98 100
stu.awk 1 2 3 4 5 6 7 8 9 10 11 12 13 14 BEGIN{ printf "%-10s%-10s%-10s%-10s%-10s%-10s\n" ,"Name" ,"Chinese" ,"Math" ,"English" ,"Physical" ,"Total" } { total=$2 +$3 +$4 +$5 yuwen_sum+=$2 math_sum+=$3 english_sum+=$4 physical_sum+=$5 printf "%-10s%-10d%-10d%-10d%-10d%-10d\n" ,$1 ,$2 ,$3 ,$4 ,$5 ,total } END{ printf "%-10s%-10d%-10d%-10d%-10d\n" ,"" ,yuwen_sum,math_sum,english_sum,physical_sum }
awk 处理数据例子 生成随机数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #!/bin/bash function create_random (){ min=$1 max=$(($2 -$min +1 )) num=$(date +%s%N) echo $(($num %$max +$min )) } INDEX=1 while true do for user in Allen Mike Jerry Tracy Hanmeimei Lilei do COUNT=$RANDOM NUM1=`create_random 1 $COUNT ` NUM2=`expr $COUNT - $NUM1 ` echo "`date '+%y-%m-%d %H:%M:%S'` $INDEX Batches: user $user insert $COUNT records into databases:product table:datail,insert $NUM1 records successfully,failed $NUM2 records" >> ./db.log.`date +%Y%m%d` INDEX=`expr $INSEX + 1` done done
统计每个用户分别插入多少record tesst.awk 1 2 3 4 5 6 7 8 9 10 BEGIN{ printf "%-10s%-10s\n" ,"User" ,"Total Records" } { USER[$6 ]+=$8 } END{ for (u in USER) printf "%-20s%-20d\n" ,u,USER[u] }
统计每个用户分别插入成功和失败各多少record 2.awk 1 2 3 4 5 6 7 8 9 10 11 BEGIN{ printf "%-10s%-20s%-20s\n" ,"User," Success_Records"," Filed_records" } { SUCCESS[$6 ]+=$14 FAILED[$6 ]+=$17 } END{ for(u in SUCCESS) printf " %-10s%-20d%-20d\n",u,SUCCESS[u],FAILED[u] }
将例子1,2结合,一起输出每个用户分别插入多少条数据,成功失败各多少条 3.awk 1 2 3 4 5 6 7 8 9 10 11 12 BEGIN{ printf "%-30s%-30s%-30s%-30s\n" ,"Name" ,"total records" ,"success records" ,"failed records" } { TOTAL_RECORDS[$6 ]+=$8 SUCCESS[$6 ]+=$14 FAILED[$6 ]+=$17 } END{ for (u in TOTAL_RECORDS) printf "%-30s%-30d%-30d%-30d\n" ,u,TOTAL_RECORDS[u],SUCCESS[u],FAILED[u] }
在例子3的基础上,加上结尾,统计全部插入记录数,成功记录数,失败记录数 3.awk 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 BEGIN{ printf "%-30s%-30s%-30s%-30s\n" ,"Name" ,"total records" ,"success records" ,"failed records" } { TOTAL_RECORDS[$6 ]+=$8 SUCCESS[$6 ]+=$14 FAILED[$6 ]+=$17 } END{ for (u in TOTAL_RECORDS) { records_sum+=TOTAL_RECORDS[u] success_sum+=SUCCESS[u] failed_sum+=FAILED[u] printf "%-30s%-30d%-30d%-30d\n" ,u,TOTAL_RECORDS[u],SUCCESS[u],FAILED[u] } printf "%-30s%-30d%-30d%-30d\n" ,"" ,records_sum,success_sum,failed_sum }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 BEGIN{ printf "%-30s%-30s%-30s%-30s\n" ,"Name" ,"total records" ,"success records" ,"failed records" } { RECORDS[$6 ]+=$8 SUCCESS[$6 ]+=$14 FAILED[$6 ]+=$17 records_sum+=$8 success_sum+=$14 failed_sum+=$17 } END{ for (u in RECORDS) printf "%-30s%-30d%-30d%-30d\n" ,u,RECORDS[u],SUCCESS[u],FAILED[u] printf "%-30s%-30d%-30d%-30d\n" ,"total" ,records_sum,success_sum,failed_sum }
查找丢失数据的现象,也就是成功+失败的记录数不等于一共插入的记录数,找出这些数据并显示行号和对应行的日志信息 1 awk '{if($8!=$14+$17) print NR,$0}' db.log.20190722