内容简介:例:例:例:
1. 变量替换
从头开始匹配,最短删除 从头开始匹配,最长删除 从尾开始匹配,最短删除 从尾开始匹配,最长删除 替换旧的字符串为新字符串,只替换第一个 替换旧的字符串为新字符串,替换所有
例:
variable_1="i love u, do you love me"
echo ${variable_1#*ov}
# e u, do you love me
echo ${variable_1##*ov}
# e me
echo ${variable_1%ov*}
# i love u, do you l
echo ${variable_1%%ov*}
# i l
echo ${variable_1/ov/bb}
# i lbbe u, do you love me
variable_1="i love u, do you love me"
variable_2=${variable_1/ov/bb}
echo $variable_2
# i lbbe u, do you lbbe me
2. 字符串处理
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 $len
2.2 获取子串在字符串中的索引位置
-
expr index "$string" "$substring"
[不是子串,而是子串切分成单个字符,查找第一个出现的字符的位置]
例:
variable_1="i love u, do you love me" variable_2="ov" expr index "$variable_1" "$variable_2" # 4 variable_2="ok" expr index "$variable_1" "$variable_2" # 4
2.3 获取子串长度
-
expr match "string substring"
[必须从头开始匹配,能匹配到的子串返回长度,支持正则]
例:
variable_1="quickstart is a app" echo `expr match "$variable_1" app` # 0 echo `expr match "$variable_1" quick` # 5 echo `expr match "$variable_1" quick.` # 6 echo `expr match "$variable_1" quick.*` # 19
2.4 子串抽取
从string的position位置开始 从position位置开始抽取length长度 从右边开始匹配 从左边开始匹配 从position位置开始抽取length长度,索引从0开始
注意:${string:position}索引从1开始,而 expr 索引从0开始
例:
variable_1="i love u, do you love me"
position=4
length=4
echo ${variable_1:position}
# ve u, do you love me
echo ${variable_1:position:length}
# ve u
echo ${variable_1: -position}
# e me
echo ${variable_1:(-position)}
# ve u, do you love me
echo ${variable_1:(-position)}
# e me
variable_2=`expr substr "$variable_1" "$position" "$length"`
echo $variable_2
# ove
3. 字符串练习
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/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 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 true
do
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!"
;;
esac
done
4. 命令替换
- `command`
- $(command)
$(())主要用来进行整数运算,包括加减乘除
例1:获取系统中的所有用户并输出(/etc/passwd)
cat /etc/passwd | cut -d ":" -f 1
#!/bin/bash
index=1
for 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/bash
nginx_process_num=$(ps -ef | grep nginx | grep -v grep | wc -l)
if [ $nginx_process_num -eq 0 ]; then
systemctl start nginx
fi
5. 有类型变量
- declare、typeset
-r 只读 -i 整数 -a 数组 -f 在脚本中显示定义的函数和函数体 -F 在脚本中显示定义的函数 -x 环境变量
如果要取消类型声明,减号变加号就行了
例:
declare -r variable_1="hello java"
variable_1="abc"
num1=10
echo $num1+1
declare -i num2=10
declare -i num3
num3=$num2+1
echo $num2+1
echo $num3
declare -f
declare -F
array=("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,否则返回num2 num1 & num2 num1不为空且不为0,返回num1,否则返回0 num1 < num2 num1小于num2,返回1,否则返回0 num1 <= num2 num1小于等于num2,返回1,否则返回0 num1 = num2 num1等于num2,返回1,否则返回0 num1 != num2 num1不等于num2,返回1,否则返回0 num1 > num2 num1大于num2,返回1,否则返回0 num1 >= num2 num1大于等于num2,返回1,否则返回0 num1 + num2 num1 - num2 num1 * num2 num1 / num2 num1 % num2
例:
num1=10 num2=20 expr $num1 + $num2 echo $(($num1 + $num2)) expr $num1 \| $num2 expr $num1 \& $num2 expr $num1 \> $num2 expr $num1 \>= $num2 expr $num1 \< $num2 expr $num1 \<= $num2 expr $num1 = $num2 expr $num1 + $num2 expr $num1 - $num2 expr $num1 \* $num2 expr $num1 / $num2 expr $num1 % $num2
练习:提示用户输入一个正整数num,然后计算1+2+3+...+num的值,必须判断num是否为正整数,不符合允许再次输入
#!/bin/bash
sum=0
while true
do
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
fi
done
7. 函数定义和使用
7.1 函数定义
function name {
}
name() {
}
例:写一个nginx的守护脚本
#!/bin/bash
this_pid=$$
while true
do
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
fi
done
7.2 传递参数
例:写一个脚本支持+-*/四种运算
#!/bin/bash
function cal {
case $2 in
+)
echo $(($1 + $3))
;;
-)
echo $(($1 - $3))
;;
\*)
echo $(($1 * $3))
;;
/)
echo $(($1 / $3))
;;
*)
echo "error input!"
;;
esac
}
cal $1 $2 $3
7.3 返回值
- return返回值,只能返回1-255之内的整数。使用return返回值,通常供其他地方调用获取状态,因此通常返回0或者1,0表示成功,1表示失败。return表示return 0
- echo返回值,可以返回任何字符结果,通常用于返回数据,比如一个字符串或列表值
例:
#!/bin/bash
this_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/bash
function get_user_list {
users=$(cat /etc/passwd | cut -d ":" -f1)
echo $users
}
index=1
user_list=$(get_user_list)
for u in $user_list
do
echo "this is the $((index++)) user: $u"
done
7.4 变量
- 使用local定义变量表示局部变量,否则一般的变量都是全局变量
- 函数内部的变量如果跟外部变量同名,则函数内部的变量替换外部的变量
7.5 函数库
例:定义一个函数库,该函数库实现以下几个函数
(1)加法函数 add (2)减法函数 reduce (3)乘法函数 multiple (4)除法函数 dived (5)打印系统运行情况的函数sys_load,该函数可以显示系统内存运行情况
base_function.lib
#!/bin/echo
function 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.lib add 1 2 reduce 11 33 multiple 3 44 divide 20 2 sys_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 whereis
locate 不同于 find,find会查找整个磁盘,而locate命令会在数据库中查找,只能查找单个文件。可以用updatedb更新数据库文件,该文件是 /var/lib/mlocate/locate.db whereis -b,只返回二进制文件,-m,只返回帮助文档文件,-s,只返回源码文件 which 只查找二进制文件
9. grep
- grep [option] [pattern] [file1,file2]
- command | grep [option] [pattern]
参数
-i 不区分大小写 -v 反向选择 -n 显示行号 -r 递归 -E 支持扩展正则表达式 -F 不按正则表达式,按字符串字面匹配 -x 匹配整行 -w 匹配整词 -c 只输出匹配到的总行数,不显示具体内容 -l 只列出文件,不显示具体内容
例:grep -E "python|PYTHON" file
egrep 和 grep -E 等价
10. sed(stream editor缩写)
10.1 sed
- sed [option] "pattern command" file
- stdout | sed [option] "pattern command" file
option
-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为like
sed -n "s/love/like/g;p" sed.txt sed -i "s/love/like/g" sed.txt
pattern
10command 匹配第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/passwd 10,/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/=" passwd
10.2 反向引用
- & 和 1 引用模式匹配到的整个串(1的时候要替换的模式匹配中的串要用小括号包围起来)
例:sed -i "s/had..p/&s/g" sed.txt 给能匹配到had..p的字符串后面加上s,hadoopx -> hadoopsx
sed -i "s/ha\(d..p\)/XX\1/g" sed.txt 给能匹配到had..p的d..p之外的串全替换成上XX,hadoopx -> XXdoopx
例:统计 mysql 配置文件各配置段的数量
#!/bin/bash
FILE_NAME=/root/script/my.cnf
function 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=0
for segament in $(get_all_segament)
do
index=`expr $index + 1`
count=`get_all_segament_count $segament`
echo "$index: $segament $count"
done
输出:
1: client 1
2: mysql 1
3: mysqld 6
4: mysqldump 3
11. awk
- awk 'BEGIN{}pattern{commands}END{}' file_name
- stdout | '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/passwd
awk 'BEGIN{FS=":"}{print $1}' /etc/passwd
awk 'BEGIN{FS=":"}{print NF}' /etc/passwd
awk '{print NR}' /etc/passwd nginx.conf
awk '{print FNR}' /etc/passwd nginx.conf
awk 'BEGIN{RS="--"}{print $0}' test.txt
echo "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&i
awk '{print FILENAME}' nginx.conf #文件有多少行就会输出多少次
awk '{print ARGC}' /etc/passwd test.txt
11.2 printf 格式化输出
%s 打印字符串 %d 打印十进制数字 %x 打印十六进制 %f 打印浮点型 %o 打印八进制 %e 打印科学计数法 %c 打印ascii码 - 左对齐 + 右对齐 # 显示八进制在前面加0,十六进制在前面加0x
例:
awk 'BEGIN{FS=":"}{printf "%s\n",$1}' /etc/passwd
awk 'BEGIN{FS=":"}{printf "%-20s %-20s\n",$1,$7}' /etc/passwd
awk 'BEGIN{FS=":"}{printf "%#o\n",$3}' /etc/passwd
11.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/passwd
11.4 动作表达式中的算术运算符
+ - * \ ^或** 乘方 ++x x++ --x x--
例:
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 num1*num2}'
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 73
Jone 83 23 38 97
Monica 99 77 89 43
Jerry 77 44 32 91
awk '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.txt
11.5 条件
if (条件表达式1)
动作1
else if (条件表达式2)
动作2
else
动作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/passwd
awk的代码可能很长,这个时候可以写成脚本用-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 73
Jone 83 23 38 97
Monica 99 77 89 43
Jerry 77 44 32 91
awk '{total=$2+$3+$4+$5;avg=total/4;if(avg>70){printf "%-10s %-0.2f\n",$1,avg}}' score.txt
11.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:x: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/passwd
awk -F: '{print $1}' /etc/passwd
11.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; done
- awk中数组的用法(索引从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 73
Jone 83 23 38 97
Monica 99 77 89 43
Jerry 77 44 32 91
awk '{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 355
Jone 83 23 38 97 241
Monica 99 77 89 43 308
Jerry 77 44 32 91 244
349 243 252 304
11.10 awk中数组的用法
例:用awk脚本处理数据并生成报告
生成数据的脚本:insert.sh
#!/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 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`
done
done
数据格式:
2019-04-17 23:44:36 495 Batches: Jerry insert 7658 data into table test1, insert 1008 records successfully, failed insert 6650 records
2019-04-17 23:44:36 496 Batches: Tracy insert 17609 data into table test1, insert 10348 records successfully, failed insert 7261 records
2019-04-17 23:44:36 497 Batches: Hanmeimei insert 14256 data into table test1, insert 1599 records successfully, failed insert 12657 records
2019-04-17 23:44:36 498 Batches: Lilei insert 9279 data into table test1, insert 7856 records successfully, failed insert 1423 records
2019-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.txt
12. mysql操作
12.1 安装启动mariadb
yum install mariadb mariadb-server mariadb-libs -y systemctl start mariadb
13. 脚本工具
脚本 工具 功能概述 (1)、实现一个脚本,该脚本提供类似supervisor的功能,可以对进程进行管理 (2)、一键查看所有进程运行状态 (3)、单个或批量启停进程 (4)、提供进程分组功能,可以按组查看进程运行状态,可以按组启停进程
配置文件 process.cfg [GROUP_LISE] WEB_LIST DB_LIST HADOOP_LIST YARN_LIST [WEB_LIST] nginx httpd [DB_LIST] mysql postgresql [HADOOP_LIST] datanode namenode [YARN_LIST] resourcemanager nodemanager [nginx] description="Web Server 1" program_name=tail parameter=-f /root/tmp/web-nginx.conf [httpd] description="Web Server 2" program_name=tail parameter=-f /root/tmp/web-httpd.conf [mysql] description="High Perfrmance Database" program_name=tail parameter=-f /root/tmp/db-mysql.conf [postgresql] description="High Perfrmance Database" program_name=tail parameter=-f /root/tmp/db-postgresql.conf [datanode] description="Hadoop datanode" program_name=tail parameter=-f /root/tmp/hadoop-datanode.conf [namenode] description="Hadoop namenode" program_name=tail parameter=-f /root/tmp/hadoop-namenode.conf [resourcemanager] description="yarn resourcemanager" program_name=tail parameter=-f /root/tmp/yarn-resourcemanager.conf [nodemanager] description="yarn nodemanager" program_name=tail parameter=-f /root/tmp/yarn-nodemanager.conf
#!/bin/bash
THIS_PID=$$
GROUP_LIST=GROUP_LIST
CFG_FILE=/root/script/tmp/process.cfg
function 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 $1
echo "********************************************************************************************************"
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.
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Master Switch
Tim Wu / Knopf / 2010-11-2 / USD 27.95
In this age of an open Internet, it is easy to forget that every American information industry, beginning with the telephone, has eventually been taken captive by some ruthless monopoly or cartel. Wit......一起来看看 《The Master Switch》 这本书的介绍吧!