- 变量替换${变量名#匹配规则} 从头开始匹配,最短删除${变量名##匹配规则} 从头开始匹配,最长删除${变量名%匹配规则} 从尾开始匹配,最短删除${变量名%%匹配规则} 从尾开始匹配,最长删除${变量名/旧字符串/新字符串} 替换旧的字符串为新字符串,只替换第一个${变量名//旧字符串/新字符串} 替换旧的字符串为新字符串,替换所有例:variable_1=“i love u, do you love me"echo ${variable_1#ov}# e u, do you love meecho ${variable_1##ov}# e meecho ${variable_1%ov}# i love u, do you lecho ${variable_1%%ov}# i lecho ${variable_1/ov/bb}# i lbbe u, do you love mevariable_1=“i love u, do you love me"variable_2=${variable_1/ov/bb}echo $variable_2# i lbbe u, do you lbbe me2. 字符串处理2.1 获取字符串长度${#string}expr length “$string"例:variable_1=“i love u, do you love me"echo ${#variable_1}expr length “$variable_1"len=
expr length "$variable_1"
echo $len2.2 获取子串在字符串中的索引位置expr index “$string” “$substring” [不是子串,而是子串切分成单个字符,查找第一个出现的字符的位置]例:variable_1=“i love u, do you love me"variable_2=“ov"expr index “$variable_1” “$variable_2”# 4variable_2=“ok"expr index “$variable_1” “$variable_2”# 42.3 获取子串长度expr match “string substring” [必须从头开始匹配,能匹配到的子串返回长度,支持正则]例:variable_1=“quickstart is a app"echo expr match "$variable_1" app
# 0echo expr match "$variable_1" quick
# 5echo expr match "$variable_1" quick.
# 6echo expr match "$variable_1" quick.*
# 192.4 子串抽取${string:position} 从string的position位置开始${string:position:length} 从position位置开始抽取length长度${string:-position} 从右边开始匹配${string:(position)} 从左边开始匹配expr substr “$string” “$position” “$length” 从position位置开始抽取length长度,索引从0开始注意:${string:position}索引从1开始,而 expr 索引从0开始例:variable_1=“i love u, do you love me"position=4length=4echo ${variable_1:position}# ve u, do you love meecho ${variable_1:position:length}# ve uecho ${variable_1: -position}# e meecho ${variable_1:(-position)}# ve u, do you love meecho ${variable_1:(-position)}# e mevariable_2=expr substr "$variable_1" "$position" "$length"
echo $variable_2# ove3. 字符串练习string=“bigdata process framework is hadoop, hadoop is an open source project"执行脚本后,打印输出string字符串变量,并给出用户以下选项:(1) 打印string长度(2) 在整个字符串中删除Hadoop(3) 替换第一个Hadoop为Mapreduce(4) 替换全部Hadoop为Mapreduce用户输入对应的数字会执行相应的功能,输入q|Q退出操作#!/bin/bashstring=“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 print_len { echo “${#string}"}function del_Hadoop { echo “${string//Hadoop/}"}function rep_Hadoop_to_Mapreduce_first { echo “${string/Hadoop/Mapreduce}"}function rep_Hadoop_to_Mapreduce_alll { echo “${string//Hadoop/Mapreduce}"}while truedo echo echo echo “【string=$string】” print_tips read -p “please input your choice(1|2|3|4|q|Q): " choice case $choice in 1) echo print_len ;; 2) echo del_Hadoop ;; 3) echo rep_Hadoop_to_Mapreduce_first ;; 4) echo rep_Hadoop_to_Mapreduce_alll ;; q|Q) exit ;; ) echo echo “error input!” ;; esacdone4. 命令替换command
$(command)$(())主要用来进行整数运算,包括加减乘除例1:获取系统中的所有用户并输出(/etc/passwd)cat /etc/passwd | cut -d “:” -f 1#!/bin/bashindex=1for user in cat /etc/passwd | cut -d ":" -f 1
do echo “this is $index user: $user” index=$(($index+1))done例2:根据系统时间计算今年、明年echo “this is $(date +%Y), next year is $(($(date +%Y)+1))“例3:根据系统时间获取今年还剩下多少个星期,已经过了多少个星期echo “今年已经过了$(date +%j)天,合$(($(date +%j) / 7))周,还剩下$(((365-$(date +%j)) / 7))周"例子4:判断nginx进程是否存在,不存在的话拉起该进程#!/bin/bashnginx_process_num=$(ps -ef | grep nginx | grep -v grep | wc -l)if [ $nginx_process_num -eq 0 ]; then systemctl start nginxfi5. 有类型变量declare、typeset-r 只读-i 整数-a 数组-f 在脚本中显示定义的函数和函数体-F 在脚本中显示定义的函数-x 环境变量如果要取消类型声明,减号变加号就行了例:declare -r variable_1=“hello java"variable_1=“abc"num1=10echo $num1+1declare -i num2=10declare -i num3num3=$num2+1echo $num2+1echo $num3declare -fdeclare -Farray=(“jane” “jone” “jack” “jordan”)输出数组内容 echo ${array[@]} 输出所有内容 echo ${array[0]} 输出下标对应的内容获取数组长度 echo ${#array} echo ${#array[0]}6. 数字运算expr $num1 operator $num2$(($num1 operator $num2))注意:expr只支持整型运算expr 操作符num1 | num2 num1不为空且不为0,返回num1,否则返回num2num1 & num2 num1不为空且不为0,返回num1,否则返回0num1 < num2 num1小于num2,返回1,否则返回0num1 <= num2 num1小于等于num2,返回1,否则返回0num1 = num2 num1等于num2,返回1,否则返回0num1 != num2 num1不等于num2,返回1,否则返回0num1 > num2 num1大于num2,返回1,否则返回0num1 >= num2 num1大于等于num2,返回1,否则返回0num1 + num2num1 - num2num1 * num2num1 / num2num1 % num2例:num1=10num2=20expr $num1 + $num2echo $(($num1 + $num2))expr $num1 | $num2expr $num1 & $num2expr $num1 > $num2expr $num1 >= $num2expr $num1 < $num2expr $num1 <= $num2expr $num1 = $num2expr $num1 + $num2expr $num1 - $num2expr $num1 * $num2expr $num1 / $num2expr $num1 % $num2练习:提示用户输入一个正整数num,然后计算1+2+3+…+num的值,必须判断num是否为正整数,不符合允许再次输入#!/bin/bashsum=0while truedo read -p “please input: " num expr $num + 1 &> /dev/null if [ $? -eq 0 ]; then if [ expr $num \> 0
-eq 1 ]; then for ((i=0;i<=$num;i++)) do sum=$(($sum + $i)) done echo $sum exit else echo “小于等于0” continue fi else echo “不是整数” continue fidone7. 函数定义和使用7.1 函数定义function name {}name() {}例:写一个nginx的守护脚本#!/bin/bashthis_pid=$$while truedo ps -ef | grep nginx | grep -v grep | grep -v $this_pid &> /dev/null if [ $? -eq 0 ]; then echo “nginx is running well!” sleep 3 else echo “starting!” systemctl nginx start sleep 1 fidone7.2 传递参数例:写一个脚本支持+-/四种运算#!/bin/bashfunction cal { case $2 in +) echo $(($1 + $3)) ;; -) echo $(($1 - $3)) ;; *) echo $(($1 * $3)) ;; /) echo $(($1 / $3)) ;; ) echo “error input!” ;; esac}cal $1 $2 $37.3 返回值return返回值,只能返回1-255之内的整数。使用return返回值,通常供其他地方调用获取状态,因此通常返回0或者1,0表示成功,1表示失败。return表示return 0echo返回值,可以返回任何字符结果,通常用于返回数据,比如一个字符串或列表值例:#!/bin/bashthis_pid=$$function is_nginx_running { ps -ef | grep nginx | grep -v grep | grep -v $this_pid &> /dev/null if [ $? -eq 0 ]; then return else return 1 fi}is_nginx_running && echo “nginx is running” || echo “nginx is down"sh -x nginx_stat.sh [-x可以查看执行过程]#!/bin/bashfunction get_user_list { users=$(cat /etc/passwd | cut -d “:” -f1) echo $users}index=1user_list=$(get_user_list)for u in $user_listdo echo “this is the $((index++)) user: $u"done7.4 变量使用local定义变量表示局部变量,否则一般的变量都是全局变量函数内部的变量如果跟外部变量同名,则函数内部的变量替换外部的变量7.5 函数库例:定义一个函数库,该函数库实现以下几个函数(1)加法函数 add(2)减法函数 reduce(3)乘法函数 multiple(4)除法函数 dived(5)打印系统运行情况的函数sys_load,该函数可以显示系统内存运行情况base_function.lib#!/bin/echofunction add { echo “expr $1 + $2
"}function reduce { echo “expr $1 - $2
"}function multiple { echo “expr $1 \* $2
"}function divide { echo “expr $1 / $2
"}function sys_load { echo “—memory info—” free -m echo echo “—disk info—” df -h}calculate.sh#!/bin/bash. /root/script/base_function.libadd 1 2reduce 11 33multiple 3 44divide 20 2sys_load库文件的后缀是任意的,但是一般以.lib使用库文件通常没有执行权限8. 常用查找命令8.1 find [路径] [选项] [操作]选项-name 根据名字-iname 根据名字,不区分大小写-perm 根据权限-prune 该选项可以排除某些查找目录-user 根据文件用主-group 根据文件属组-mtime -n|+n 根据文件更改时间,-n表示n天以内修改的文件,+n表示n天意外修改的文件-mmin -n|+n 根据文件更改时间,-n表示n分钟以内修改的文件,+n表示n分钟意外修改的文件-newer file1 ! file2 比file1新但是比file2旧的文件-type 根据文件类型 f-文件,d-目录,l-管道文件-size -n +n 根据文件大小-mindepth n 从n级子目录开始搜索-maxdepth n 最多搜索到n级子目录-a 与-o 或!|-not 非操作-print 默认操作-exec 对搜索到的文件执行特定操作,格式为 -exec command {} ; ,其中{}代表搜索到的文件,如:find . -name “.conf” -exec rm -rf {} ;-ok 跟-exec一样,只是每次操作都会给用户提示例:将/var/log目录下以log结尾,且更改时间在7天以上的删除find /var/log -name “log” -mtime +7 -exec rm -rf {} ;8.2 locate which whereislocate 不同于 find,find会查找整个磁盘,而locate命令会在数据库中查找,只能查找单个文件。可以用updatedb更新数据库文件,该文件是 /var/lib/mlocate/locate.dbwhereis -b,只返回二进制文件,-m,只返回帮助文档文件,-s,只返回源码文件which 只查找二进制文件9. grepgrep [option] [pattern] [file1,file2]command | grep [option] [pattern]参数-i 不区分大小写-v 反向选择-n 显示行号-r 递归-E 支持扩展正则表达式-F 不按正则表达式,按字符串字面匹配-x 匹配整行-w 匹配整词-c 只输出匹配到的总行数,不显示具体内容-l 只列出文件,不显示具体内容例:grep -E “python|PYTHON” fileegrep 和 grep -E 等价10. sed(stream editor缩写)10.1 sedsed [option] “pattern command” filestdout | sed [option] “pattern command” fileoption-n 只打印模式匹配行。sed -n “/python/p” sed.txt-e 直接在命令行编辑。sed -n -e “/PYTHON/p” -e “/python/p” sed.txt,多重处理的时候用-e连接-f 指定编辑处理的 pattern command 内容。sed -n edit.sed sed.txt,edit.sed中的内容是/python/p-r pattern支持扩展正则表达式。sed -n -r “/python|PYTHON/p” sed.txt-i 对源文件进行修改例:替换文件中love为likesed -n “s/love/like/g;p” sed.txtsed -i “s/love/like/g” sed.txtpattern10command 匹配第10行10,20command 匹配第10-20行10,+5command 匹配第10-16行/pattern1/command 匹配pattern1的行。sed -n “//spool//p” /etc/passwd,匹配带有/spool/的行。sed -n “/^daemon/p” /etc/passwd,匹配daemon开头的行/pattern1/,/pattern2/command 匹配pattern1到pattern2的行结束。sed -n “/^daemon/p” /etc/passwd10,/pattern1/command 从第10行开始匹配到第一个pattern1的行结束/pattern1/,10command 连续匹配10行command查询 p 打印增加 a 行后追加。sed -i “//bin/bash/a this user can login to system” passwd i 行前追加 r 外部文件读入,行尾追加 w 匹配行写入外部文件删除 d 删除不能登录的用户,sed -i “//sbin/nologin/d” passwd。删除从mail开头的行到ftp开头的行,sed -i “/^mail/,/^ftp/d” passwd 例:删除配置文件中的所有空行和注释行。sed -i “/^$/d;/[:blank:]#/d;/\t/d” nginx.conf,[:blank:]匹配空格,\t匹配tab 例:在配置文件中所有不以#开头的行前面添加符号(#开头的行不添加)。sed -i “s/^([^#])/*\1/g” nginx.conf 或者 sed -i “s/^[^#]/&/g” nginx.conf更改 s/old/new/ 将行内第一个替换 s/old/new/g 将行内所有替换 s/old/new/2 将行内第二个替换 s/old/new/2g 从第二个开始替换所有的 s/old/new/ig 忽略大小写 例:删掉所有的数字。sed -i “s/[0-9]+//g” sed.txt其它 = 显示行号。sed -n “//sbin/nologin/=” passwd10.2 反向引用& 和 1 引用模式匹配到的整个串(1的时候要替换的模式匹配中的串要用小括号包围起来)例:sed -i “s/had..p/&s/g” sed.txt 给能匹配到had..p的字符串后面加上s,hadoopx -> hadoopsxsed -i “s/ha(d..p)/XX\1/g” sed.txt 给能匹配到had..p的d..p之外的串全替换成上XX,hadoopx -> XXdoopx例:统计mysql配置文件各配置段的数量#!/bin/bashFILE_NAME=/root/script/my.cnffunction get_all_segament { sed -n ‘/[.]/p’ $FILE_NAME | sed -e “s/[//g” | sed -e “s/]//g” # 查找[开头]结尾的行,并且删除掉[和]}function get_all_segament_count { count=sed -n "/\[$1\]/,/\[.*\]/p" $FILE_NAME | grep -v "^#" | grep -v "^$" | grep -v "\[.*\]" | wc -l
# 查找[$1]开头的行到发现[.]的行结束,去掉#开头和空行,并去掉[.]的行(即开头和结束的行),统计数量 echo $count}index=0for segament in $(get_all_segament)do index=expr $index + 1
count=get_all_segament_count $segament
echo “$index: $segament $count"done输出:1: client 12: mysql 13: mysqld 64: mysqldump 311. awkawk ‘BEGIN{}pattern{commands}END{}’ file_namestdout | ‘BEGIN{}pattern{commands}END{}‘BEGIN{} 正式处理之前执行的pattern 匹配模式{commands} 执行命令(可能多行)END{} 处理完所有的匹配数据之后执行11.1 内置变量$0 整行内容$1-$n 本行中按照某个字符分隔后的第n个变量NF 当前行的字段个数,也就是列的个数(Number Field)NR 当前行的行号,从1开始计算(Number Row)FNR 多文件处理时,每个文件行号单独计数,都是从1开始(File Number Row)FS 输入字段分隔符,不输入默认是空格或者tab键分隔(Field Separator)RS 输入行分隔符。默认回车换行(Row Separator)OFS 输出字段分隔符。默认空格ORS 输出行分隔符。默认回车FILENAME 处理的文件名ARGC 命令行参数个数ARGV 命令行参数数组例:打印/etc/passwd文件的内容awk ‘{print $0}’ /etc/passwdawk ‘BEGIN{FS=”:”}{print $1}’ /etc/passwdawk ‘BEGIN{FS=”:”}{print NF}’ /etc/passwdawk ‘{print NR}’ /etc/passwd nginx.confawk ‘{print FNR}’ /etc/passwd nginx.confawk ‘BEGIN{RS=”–”}{print $0}’ test.txtecho “a-b-c–d-e-f–g-h-i” | awk ‘BEGIN{RS=”–";FS=”-”}{print $3}’echo “a-b-c–d-e-f–g-h-i” | awk ‘BEGIN{RS=”–";FS=”-";ORS="|";OFS="&”}{print $1,$2,$3}’ #必须用逗号分隔,否则输出字段分隔符不会起作用。a&b&c|d&e&f|g&h&iawk ‘{print FILENAME}’ nginx.conf #文件有多少行就会输出多少次awk ‘{print ARGC}’ /etc/passwd test.txt11.2 printf 格式化输出%s 打印字符串%d 打印十进制数字%x 打印十六进制%f 打印浮点型%o 打印八进制%e 打印科学计数法%c 打印ascii码- 左对齐+ 右对齐# 显示八进制在前面加0,十六进制在前面加0x例:awk ‘BEGIN{FS=”:”}{printf “%s\n”,$1}’ /etc/passwdawk ‘BEGIN{FS=”:”}{printf “%-20s %-20s\n”,$1,$7}’ /etc/passwdawk ‘BEGIN{FS=”:”}{printf “%#o\n”,$3}’ /etc/passwd11.3 模式匹配的两种方式正则表达式按关系运算符匹配><== 可以用于数值和字符串<=>=!=~ 匹配正则表达式!~ 不匹配正则表达式&&||!例:匹配/etc/passwd中包含root的行。 awk ‘/root/{print $0}’ /etc/passwd匹配/etc/passwd中以root开头的行。 awk ‘/^root/{print $0}’ /etc/passwd匹配/etc/passwd中第3个字段大于50的行。 awk ‘BEGIN{FS=”:”}$3>50{printf “%s\n”,$0}’ /etc/passwd匹配/etc/passwd中第7个字段等于/sbin/nologin的行。 awk ‘BEGIN{FS=”:”}$7=="/sbin/nologin”{printf “%s\n”,$7}’ /etc/passwd匹配/etc/passwd中第7个字段不等于/sbin/nologin的行。 awk ‘BEGIN{FS=”:”}$7!="/sbin/nologin”{printf “%s\n”,$7}’ /etc/passwd匹配/etc/passwd中第3个字段包含三个以上数字的行(匹配正则表达式)。 awk ‘BEGIN{FS=”:”}$3~/[0-9]{3,}/{printf “%d\n”,$3}’ /etc/passwd匹配/etc/passwd中包含root或nologin的所有行。awk ‘/root/ || /nologin/{print $0}’ /etc/passwd匹配/etc/passwd中第3个字段包含小于50并且第4个字段大于60并且第7行包含/sbin/nologin的所有行 awk ‘BEGIN{FS=”:”}$3>50 && $4<60 && $7~//sbin/nologin/{printf “%s %s %s\n”,$3,$4,$7}’ /etc/passwd11.4 动作表达式中的算术运算符+-^或 乘方++xx++–xx–例:awk ‘BEGIN{var1=10;var2=“hello”;print var1,var2}‘awk ‘BEGIN{num1=10;num2+=num1;print num1,num2}‘awk ‘BEGIN{num1=10;num2=29;print num1+num2}‘awk ‘BEGIN{num1=10;num2=29;print num1-num2}‘awk ‘BEGIN{num1=10;num2=29;print num1num2}‘awk ‘BEGIN{num1=10;num2=29;print num1/num2}‘awk ‘BEGIN{num1=10;num2=29;print num1^num2}‘awk ‘BEGIN{x=10;y=20;print x++;y++}‘awk ‘BEGIN{x=10;y=20;print ++x;++y}‘awk ‘BEGIN{num1=10;num2=29;printf “%0.2f\n”,num1/num2}’ #保留两位小数例:使用awk计算某文件中空白行的数量awk ‘/^$/{sum++}END{print sum}’ my.cnf例:计算课程分数平均值Allen 90 99 93 73Jone 83 23 38 97Monica 99 77 89 43Jerry 77 44 32 91awk ‘BEGIN{printf “%-8s %-8s %-8s %-8s %-8s\n”,“姓名”,“语文”,“数学”,“物理”,“平均分”}{total=$2+$3+$4+$5;avg=total/4;printf “%-8s %-8d %-8d %-8d %-8d %0.2f\n”,$1,$2,$3,$4,$5,avg}’ score.txt11.5 条件if (条件表达式1) 动作1else if (条件表达式2) 动作2else 动作3例:awk ‘BEGIN{FS=”:"}{if($3<50) {printf “%-10s %-4d\n”,“小于50的uid”,$3} else if($3<80) {printf “%-10s %-4d\n”,“小于80的uid”,$3} else {printf “%-10s %-4d\n”,“其它uid”,$3}}’ /etc/passwdawk的代码可能很长,这个时候可以写成脚本用-f来调用BEGIN { FS=":"}{ if($3<50) { printf “%-10s %-4d\n”,“小于50的uid”,$3 } else if($3<80) { printf “%-10s %-4d\n”,“小于80的uid”,$3 } else { printf “%-10s %-4d\n”,“其它uid”,$3 }}awk -f script.awk /etc/passwd例:计算课程分数平均值,并且只打印分数大于70的同学的姓名和分数Allen 90 99 93 73Jone 83 23 38 97Monica 99 77 89 43Jerry 77 44 32 91awk ‘{total=$2+$3+$4+$5;avg=total/4;if(avg>70){printf “%-10s %-0.2f\n”,$1,avg}}’ score.txt11.6 循环while(条件表达式) 动作do 动作while(条件表达式)for(初始化计数器;测试计数器;计数器变更) 动作例:计算1+2+3+…+100的和,分别使用do-while、while、for实现awk ‘BEGIN{for(i=1;i<=100;i++){sum+=i};printf “sum=%d\n”,sum}‘awk ‘BEGIN{do{sum+=i++}while(i<=100);printf “sum=%d\n”,sum}‘awk ‘BEGIN{while(i<=100){sum+=i++};printf “sum=%d\n”,sum}‘11.7 字符串函数函数名 解释 函数返回值———————————————————————————————————–length(str) 计算字符串长度 整数返回值index(str1,str2) 在str1中查找str2的位置 返回值为索引,从1开始toupper(str) 转换为大写 转换后的大写字符串tolower(str) 转换为小写 转换后的小写字符串substr(str,m,n) 从str的m个字符截取n位 截取后的子串split(str,arr,fs) 按fs切割字符串,结果保存到arr(分隔符默认是空格,可以省略) 切割后的子串的个数match(str,RE) 在str中按照RE查找,返回位置 返回索引位置,从1开始sub(RE,RepStr,str) 在str中按RE搜索字符串并将其替换为RepStr,只替换第一个,返回替换的个数gsub(RE,RepStr,str) 在str中按RE搜索字符串并将其替换为RepStr,替换所有例:awk ‘BEGIN{print length(“abcd”)}‘awk ‘BEGIN{print index(“abcd”,“c”)}‘awk ‘BEGIN{print toupper(“abCd”)}‘awk ‘BEGIN{print tolower(“abCd”)}‘awk ‘BEGIN{print substr(“hello,world”,3,6)}‘awk ‘BEGIN{print split(“root❌0:0:root”,arr,":");print arr}‘awk ‘BEGIN{print match(“hello,world”, /lo/)}‘例:返回/etc/passwd中每个字段的长度awk ‘BEGIN{FS=":";OFS=":"}{print length($1),length($2),length($3),length($4),length($5),length($6),length($7)}’ /etc/passwd搜索"i have a dream"中ea的位置awk ‘BEGIN{print index(“i have a dream”,“ea”)}‘awk ‘BEGIN{print match(“i have a dream”,“ea”)}‘将"Hadoop is a bigdata framework"转换为小写awk ‘BEGIN{print tolower(“Hadoop is a bigdata framework”)}‘将"Hadoop is a bigdata framework"转换为大写awk ‘BEGIN{print toupper(“Hadoop is a bigdata framework”)}‘将"Hadoop is a bigdata framework"按空格分割后保存在数组中awk ‘BEGIN{str=“Hadoop is a bigdata framework”;split(str,arr," “);for(a in arr){print arr[a]}}‘找出字符串"Transaction 23345 start: select * from master"中第一个数字出现的位置awk ‘BEGIN{str=“Transaction 23345 start: select * from master”;print match(str,/[0-9]/)}‘截取字符串"Transaction 23345 start: select * from master”,从第4个开始截取5位awk ‘BEGIN{str=“Transaction 23345 start: select * from master”;print substr(str,4,5)}‘替换"Transaction 23345 start, Event ID: 9002"中出现的第一个数字串为$awk ‘BEGIN{str=“Transaction 23345 start, Event ID: 9002”;count=sub(/[0-9]+/,"$",str);print count,str}‘11.8 选项-v 参数传递-f 指定awk脚本文件-F 指定分隔符,可以连着写-V 查看awk版本例:awk -v arg1=12 -v arg2=“hello world” ‘BEGIN{print arg1,arg2}‘awk -F “:” ‘{print $1}’ /etc/passwdawk -F: ‘{print $1}’ /etc/passwd11.9 awk中数组的用法数组使用(索引从0开始)array=(“janee” “jone” “jacek” “jordan”)打印元素 echo ${array[0]}、echo ${array[@]}打印元素个数 echo ${#array[@]}打印元素长度 echo ${#array[0]}给元素赋值 array[2]=“messi"删除元素 unset array[2]、unset array分片访问 echo ${array[0]:1:3}元素替换 ${array[@]/e/E}(替换元素中的第一个e为E)、${array[@]//e/E}(替换元素中的所有e为E)元素便利 for a in ${array[@]}; do echo $a; doneawk中数组的用法(索引从1开始)awk ‘BEGIN{str=“hadoop spark yarn storm flume”;split(str,array,” “);for(i=1;i<=length(array);i++){print array[i]}}‘awk的数组中可以使用字符串作为数组的下标awk ‘BEGIN{array[“var1”]=“zhangsan”;array[“var2”]=“lisi”;array[“var3”]=“wangwu”;for(i in array){print array[i]}}‘例:统计各种tcp状态连接状态数netstat -an | grep tcp | awk ‘{array[$6]++}END{for(i in array){print i,array[i]}}‘例:计算纵向横向总和Allen 90 99 93 73Jone 83 23 38 97Monica 99 77 89 43Jerry 77 44 32 91awk ‘{line++;line_sum=0;for(i=1;i<=NF;i++){line_sum+=$i;col_sum[i]+=$i;printf “%-6s “,$i};print line_sum}END{printf “%-6s”,”";for(i=2;i<=length(col_sum);i++){printf “%-6s “,col_sum[i]};printf “\n”}’ score.txt输出:Allen 90 99 93 73 355Jone 83 23 38 97 241Monica 99 77 89 43 308Jerry 77 44 32 91 244 349 243 252 304 11.10 awk中数组的用法例:用awk脚本处理数据并生成报告生成数据的脚本:insert.sh#!/bin/bashfunction create_random { min=$1 max=$(($2-$min+1)) num=$(date +%s%N) echo $(($num%$max+$min))}INDEX=1while truedo for user in Mike Allen 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 insert $COUNT data into table ’test1’, insert $NUM1 records successfully, failed insert $NUM2 records >> /root/script/data.txt INDEX=expr $INDEX + 1
donedone数据格式:2019-04-17 23:44:36 495 Batches: Jerry insert 7658 data into table test1, insert 1008 records successfully, failed insert 6650 records2019-04-17 23:44:36 496 Batches: Tracy insert 17609 data into table test1, insert 10348 records successfully, failed insert 7261 records2019-04-17 23:44:36 497 Batches: Hanmeimei insert 14256 data into table test1, insert 1599 records successfully, failed insert 12657 records2019-04-17 23:44:36 498 Batches: Lilei insert 9279 data into table test1, insert 7856 records successfully, failed insert 1423 records2019-04-17 23:44:36 499 Batches: Mike insert 22652 data into table test1, insert 6291 records successfully, failed insert 16361 records(1)、统计每个人员插入了多少条数据进数据库awk ‘BEGIN{printf “%-10s %-10s\n”,“name”,“total”}{stat[$5]+=$7}END{for(i in stat){printf “%-10s %-10s\n”,i,stat[i]}}’ data.txt(2)、统计每个人员插入成功和失败了多少条数据进数据库awk ‘BEGIN{printf “%-10s %-10s %-10s %-10s\n”,“User”,“Total”,“Succeed”,“Failed”}{sum[$5]+=$7;suc_sum[$5]+=$13;fail_sum[$5]+=$18}END{for(i in sum){printf “%-10s %-10s %-10s %-10s\n”,i,sum[i],suc_sum[i],fail_sum[i]}}’ data.txt(3)、在(2)的基础上统计全部插入记录数awk ‘BEGIN{printf “%-10s %-10s %-10s %-10s\n”,“User”,“Total”,“Succeed”,“Failed”}{sum[$5]+=$7;suc_sum[$5]+=$13;fail_sum[$5]+=$18}END{for(i in sum){all_sum+=sum[i];all_suc_sum+=suc_sum[i];all_fail_sum+=fail_sum[i];printf “%-10s %-10s %-10s %-10s\n”,i,sum[i],suc_sum[i],fail_sum[i]};printf “%-10s %-10s %-10s %-10s\n”,”",all_sum,all_suc_sum,all_fail_sum}’ data.txt(4)、查找丢失数据,也就是成功+失败的记录数不等于总共插入的记录数awk ‘{if($7!=$13+$18){print $0}}’ data.txt12. mysql操作12.1 安装启动mariadbyum install mariadb mariadb-server mariadb-libs -ysystemctl start mariadb13. 脚本工具脚本工具功能概述(1)、实现一个脚本,该脚本提供类似supervisor的功能,可以对进程进行管理(2)、一键查看所有进程运行状态(3)、单个或批量启停进程(4)、提供进程分组功能,可以按组查看进程运行状态,可以按组启停进程配置文件 process.cfg[GROUP_LISE]WEB_LISTDB_LISTHADOOP_LISTYARN_LIST[WEB_LIST]nginxhttpd[DB_LIST]mysqlpostgresql[HADOOP_LIST]datanodenamenode[YARN_LIST]resourcemanagernodemanager[nginx]description=“Web Server 1"program_name=tailparameter=-f /root/tmp/web-nginx.conf[httpd]description=“Web Server 2"program_name=tailparameter=-f /root/tmp/web-httpd.conf[mysql]description=“High Perfrmance Database"program_name=tailparameter=-f /root/tmp/db-mysql.conf[postgresql]description=“High Perfrmance Database"program_name=tailparameter=-f /root/tmp/db-postgresql.conf[datanode]description=“Hadoop datanode"program_name=tailparameter=-f /root/tmp/hadoop-datanode.conf[namenode]description=“Hadoop namenode"program_name=tailparameter=-f /root/tmp/hadoop-namenode.conf[resourcemanager]description=“yarn resourcemanager"program_name=tailparameter=-f /root/tmp/yarn-resourcemanager.conf[nodemanager]description=“yarn nodemanager"program_name=tailparameter=-f /root/tmp/yarn-nodemanager.conf#!/bin/bashTHIS_PID=$$GROUP_LIST=GROUP_LISTCFG_FILE=/root/script/tmp/process.cfgfunction group_list { group_list=sed -n "/\[$GROUP_LIST\]/,/^\[.*\]/p" $CFG_FILE | grep -v "^$" | grep -v "\[.*\]" | grep -v "\#"
echo $group_list}function get_all_process { for group in $(group_list) do p_list=$(get_all_process_by_group $group) echo $p_list done}function get_all_process_by_group { group_process=sed -n "/\[$1\]/,/\[.*\]/p" $CFG_FILE | grep -v "^$" | grep -v "\[.*\]" | grep -v "\#"
echo $group_process}function is_group_exists { count=sed -n "/\[$1\]/p" $CFG_FILE | grep -v "$GROUP_LIST" | wc -l
if [ $count -eq 1 ]; then return 0 else return 1 fi}function get_group_by_process_name { for g in $(group_list) do for p in get_all_process_by_group $g
do if [ $p == $1 ]; then echo “$g” fi done done}function get_process_info_by_pid { ps -ef | awk -v pid=$1 ‘$2==pid{print}’ &> /dev/null if [ $? -eq 0 ]; then proc_status=“RUNNING” else proc_status=“STOPPED” fi proc_cpu=ps aux | awk -v pid=$1 '$2==pid{print $3}'
proc_mem=ps aux | awk -v pid=$1 '$2==pid{print $4}'
proc_start_time=ps -p $1 -o lstart | grep -v "STARTED"
}function get_pid_by_process_name { if [ $# -ne 1 ]; then return 1 else pid=ps -ef | grep "$1" | grep -v grep | grep -v "$0" | awk '{print $2}'
echo $pid fi}function format_print { group=get_group_by_process_name $1
ps -ef | grep $1 | grep -v grep | grep -v $THIS_PID &> /dev/null if [ $? -eq 0 ]; then for pids in get_pid_by_process_name $1
do for _pid in $pids do get_process_info_by_pid $_pid awk -v p_name="$1” \ -v p_group="$group” \ -v p_id="$_pid” \ -v p_status="$proc_status” \ -v p_cpu="$proc_cpu” \ -v p_mem="$proc_mem” \ -v p_start_time="$proc_start_time” \ ‘BEGIN{printf “%-20s%-10s%-10s%-10s%-10s%-10s%-10s\n”,p_name,p_group,p_status,p_id,p_cpu,p_mem,p_start_time;}’ done done else awk -v p_name="$1” \ -v p_group="$group” \ ‘BEGIN{printf “%-20s%-10s%-10s%-10s%-10s%-10s%-10s\n”,p_name,p_group,“NULL”,“NULL”,“NULL”,“NULL”,“NULL”;}’ fi}echo ““echo group_list
echo get_all_process
echo get_all_process_by_group DB_LIST
echo is_group_exists WEB_LIST
echo $(get_group_by_process_name mariadb)format_print $1echo “***“14. 其它ps -ef | grep nginx | awk ‘{print $2}’ | xargs kill$? 命令执行的结果,0表示成功,其它表示有异常$$ 脚本执行的子进程的pid$# 参数数量$0 shell文件名$@ shell执行的时候传入的所有参数shift shell执行的时候跳过一个传入的参数netstat -l[listening] -a[all] -t[tcp] -p[program] Show the PID and name of the program to which each socket belongs.