最近给双十一晚会做直播,并且双十一红包一角标广告形式投放出去,在预热阶段需要看下效果,数据团队没法给出一些指标数据,需要我们自己做数据分析给出,平时shell使用的少,很多数据分析的命令忘记了,趁此机会总结下:
shell文件头
需要定义解释器:
#!/bin/bash
执行方式
第一种,作为程序执行:
chmod +x ./red-data.sh #给脚本添加执行权限
./
red-data.sh
#执行脚本
第二种,作为解释器参数执行:
/bin/sh
red-data.sh
变量
定义:
shell中没有变量类型的概念,并且不需要提前声明,赋值=号左右不能有空格,如:
variableName="value"
如果shell中没有给变量赋值,则默认是空
调用变量:
只需要在变量名字前加$即可调用,但是有时候为限定变量名的边界,需要大括号{}
site="youku"
echo $site
echo ${site}is playing video
设置只读变量
site="youku"
readonly site
myUrl="tudou"
[root@a05.pre.ad.youku]$ site="tudou"
-bash: site: readonly variable
删除变量:
使用unset删除变量,但是不能删除只读变量:
unset variable_name
特殊变量、参数
$0 shell中在$0中存放了脚本本身的名字,
$? 是显示最后命令的退出状态,
0
表示没有错误,其他表示有错误
$! shell把最后一个发送到后台进程的id
$$ 登录shell的进程id
$# 存放命令行中输入参数的个数,通常用来校验输入参数是否正确使用
$* 传递给程序的所有参数,在参数个数不确定时候,很有用
${n} 如果传递9个以上参数,不能用$10、$11来去参数,必须使用${10}、${11}
$@ 用法,$@要使用双引号括起来,否则和$*的用法相同了:
变量替换
${parameter:-value} 是如果parameter不为空就替换为它的值,为空就替换为value
${parameter:=value} 是parameter为空时,不但使用value,而且把它赋值给parameter(注意=),这种方法
不能给位置参数赋值,parameter不能是数字
${parameter:?value} 是parameter不为空,shell就替换它的值,否则shell把value写入标准错误,然后退出(这种情况发生在登录shell中,不会冲系统注销)
${parameter:+value} 是如果parameter不为空就替换为value,否则什么也不替换
引用
单引号
单引号忽略所有特殊符号
双引号
部分特殊符号不被忽略
A)美元符号
B)反引号
B)反斜杠
双引号中用反斜杠去掉字符的特殊意义(美元符号、反斜杠、反引号、换行符、其它双引号),但是反斜杠在其它特殊符号前,双引号要把它忽略。
15:03 [root@a05.pre.ad.youku]$ echo "\ hello world \$y and \"$x\""
\ hello world $y and ""
第一个空格前的反斜杠没有被忽略,显示出来
反斜杠
续行、转义
反引号
告诉shell执行括起来的命令
$(...)结构
格式:$(command) 和反引号功能一样
14:59 [root@a05.pre.ad.youku]$ echo "there are $(who | wc -l) user login in"
there are 3 user login in
expr命令
expr只是整数计算,如果浮点型的计算,可以使用awk或bc计算
此命令支持的操作符有加(+)、减(-)、乘(*)、除(/)、求模(%),其中乘法*需要用反斜杠,因为linux中*会解析为当前目录下所有文件的名字
运算
算数运算
运算符 | 说明 | 举例 |
---|---|---|
+ | 加法 | `expr $a + $b` 结果为 30。 |
- | 减法 | `expr $a - $b` 结果为 10。 |
* | 乘法 | `expr $a \* $b` 结果为 200。 |
/ | 除法 | `expr $b / $a` 结果为 2。 |
% | 取余 | `expr $b % $a` 结果为 0。 |
= | 赋值 | a=$b 将把变量 b 的值赋给 a。 |
== | 相等。用于比较两个数字,相同则返回 true。 | [ $a == $b ] 返回 false。 |
!= | 不相等。用于比较两个数字,不相同则返回 true。 | [ $a != $b ] 返回 true。 |
注意:乘法运算需要加反斜杠
关系运算
关系运算符只支持数字,不支持字符串,除非字符串的值是数字
运算符 | 说明 | 举例 |
---|---|---|
-eq | 检测两个数是否相等,相等返回 true。 | [ $a -eq $b ] 返回 true。 |
-ne | 检测两个数是否相等,不相等返回 true。 | [ $a -ne $b ] 返回 true。 |
-gt | 检测左边的数是否大于右边的,如果是,则返回 true。 | [ $a -gt $b ] 返回 false。 |
-lt | 检测左边的数是否小于右边的,如果是,则返回 true。 | [ $a -lt $b ] 返回 true。 |
-ge | 检测左边的数是否大等于右边的,如果是,则返回 true。 | [ $a -ge $b ] 返回 false。 |
-le | 检测左边的数是否小于等于右边的,如果是,则返回 true。 | [ $a -le $b ] 返回 true。 |
布尔运算
运算符 | 说明 | 举例 |
---|---|---|
! | 非运算,表达式为 true 则返回 false,否则返回 true。 | [ ! false ] 返回 true。 |
-o | 或运算,有一个表达式为 true 则返回 true。 | [ $a -lt 20 -o $b -gt 100 ] 返回 true。 |
-a | 与运算,两个表达式都为 true 才返回 true。 | [ $a -lt 20 -a $b -gt 100 ] 返回 false。 |
字符串运算
运算符 | 说明 | 举例 |
---|---|---|
= | 检测两个字符串是否相等,相等返回 true。 | [ $a = $b ] 返回 false。 |
!= | 检测两个字符串是否相等,不相等返回 true。 | [ $a != $b ] 返回 true。 |
-z | 检测字符串长度是否为0,为0返回 true。 | [ -z $a ] 返回 false。 |
-n | 检测字符串长度是否为0,不为0返回 true。 | [ -z $a ] 返回 true。 |
str | 检测字符串是否为空,不为空返回 true。 | [ $a ] 返回 true。 |
文件运算
用于检测Unix文件的各种属性
操作符 | 说明 | 举例 |
---|---|---|
-b file | 检测文件是否是块设备文件,如果是,则返回 true。 | [ -b $file ] 返回 false。 |
-c file | 检测文件是否是字符设备文件,如果是,则返回 true。 | [ -b $file ] 返回 false。 |
-d file | 检测文件是否是目录,如果是,则返回 true。 | [ -d $file ] 返回 false。 |
-f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 | [ -f $file ] 返回 true。 |
-g file | 检测文件是否设置了 SGID 位,如果是,则返回 true。 | [ -g $file ] 返回 false。 |
-k file | 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 | [ -k $file ] 返回 false。 |
-p file | 检测文件是否是具名管道,如果是,则返回 true。 | [ -p $file ] 返回 false。 |
-u file | 检测文件是否设置了 SUID 位,如果是,则返回 true。 | [ -u $file ] 返回 false。 |
-r file | 检测文件是否可读,如果是,则返回 true。 | [ -r $file ] 返回 true。 |
-w file | 检测文件是否可写,如果是,则返回 true。 | [ -w $file ] 返回 true。 |
-x file | 检测文件是否可执行,如果是,则返回 true。 | [ -x $file ] 返回 true。 |
-s file | 检测文件是否为空(文件大小是否大于0),不为空返回 true。 | [ -s $file ] 返回 true。 |
-e file | 检测文件(包括目录)是否存在,如果是,则返回 true。 | [ -e $file ] 返回 true。 |
控制流
if条件判断
主要有以下几种格式:
if ... fi 语句;
if ... else ... fi 语句;
if ... elif ... else ... fi 语句。
例如:
#!/bin/bash
echo "开始处理点播散投-----------"
if [ -n "$1" ]
then
dt=$1
else
dt=`date -d "1 day ago" "+%Y%m%d"`
fi
echo "正在查询日期:"${dt}
注意:[ expression ] expression与[]之间一定要有空格,否则语法错误
if ... else 语句也经常与 test 命令结合使用
#!/bin/bash
num1=$[2*3]
num2=$[1+5]
if test $[num1] -eq $[num2]
then
echo ‘The two numbers are equal!‘
else
echo ‘The two numbers are not equal!
fi
执行:
15:20 [root@a05.pre.ad.youku]$ sh test.sh
‘The two numbers are equal!‘
for循环
格式一:
for i in 1 2 3
do
echo $i
done
列出当前目录下所有文件
for file in *
do
echo $file
done
格式二:
不带参数的for循环,这种特殊格式,shell自动将命令行的所有参数注册列表
for var
do
command
......
done
相当于
for var in “$@”
do
command
......
done
while循环
只要while循环后的命令状态为0,循环就会一直执行下去
格式:
while command1
do
command
command
...
done
util命令
与while不同的是,只有util后的命令状态不为0,就会一直执行下去
格式:
util commond1
do
command
......
done
case逻辑
case可以将一个值与多个值比较
格式:
case value in
part1) command
......
command;;
........
partn) command
......
command;;
esac
把value依次与part1.....partn比较,发现匹配,则执行匹配项和双分号之间的所有命令,没有匹配则不执行。
例如:
#!/bin/bash
if [ "$#" -ne 1 ]
then
echo "用法:number数字"
exit 1
fi
case "$1"
in
0) echo zero;;
1) echo one;;
2) echo two;;
3) echo three;;
4) echo four;;
5) echo five;;
esac
case中还支持正则表达式匹配,例如万能匹配*
#!/bin/bash
if [ "$#" -ne 1 ]
then
echo "用法:number数字"
exit 1
fi
case "$1"
in
0) echo zero;;
1) echo one;;
2) echo two;;
3) echo three;;
4) echo four;;
5) echo five;;
*) echo "any thing"
esac
case的匹配条件可以使用 | 逻辑或
例如:
#!/bin/bash
if [ "$#" -eq 0 -o "$#" -gt 1 ]
then
hour=$(date +%H)
else
hour="$1"
fi
case $hour
in
0? | 1[01] ) echo "Good morning";;
1[2-7] ) echo "Good afternoon";;
* ) echo "Good evening";;
esac
break、continue
break和所有程序的意思是一样的,跳出所有循环,但break后边可以跟数字参数,标示跳出第几层循环,默认不写表示跳出本层循环
如:
break n
表示跳出第 n 层循环
#!/bin/bash
for var1 in 1 2 3
do
for var2 in 0 5
do
if [ $var1 -eq 2 -a $var2 -eq 0 ]
then
break 2
else
echo "$var1 $var2"
fi
done
done
执行结果:
15:42 [root@a05.pre.ad.youku]$ sh test-break.sh
1 0
1 5
continue 后面也可以跟一个数字,表示跳出第几层循环
字符串
拼接
shell中字符串拼接异常的简单,直接放到一起即可,如:
15:50 [root@a05.pre.ad.youku]$
echo "welcome to "$site
welcome to youku
获取长度
15:58 [root@a05.pre.ad.youku]$ site="youku"
tty:[0] jobs:[1] cwd:[/opt/flamegraph]
15:58 [root@a05.pre.ad.youku]$ echo ${#site}
5
截取
16:00 [root@a05.pre.ad.youku]$ site="youku"
tty:[0] jobs:[1] cwd:[/opt/flamegraph]
16:01 [root@a05.pre.ad.youku]$ echo ${site:1:3}
ouk
截取第1-3个字符
数组
shell中支持一维数组,使用和程序语言是一样的,下标也是从0开始计算index
定义格式:
空格分开
array_name=(value0 value1 value2 value3)
换行
array_name=(
value0
value1
value2
value3
)
也可以单独定义数组的各个分量:
array_name[0]=value0
array_name[1]=value1
array_name[2]=value2
读取
valuen=${array_name[2]}
使用@ 或 * 可以获取数组中的所有元素,例如:
${array_name[*]}
${array_name[@]}
获取长度
获取数组长度的方法与获取字符串长度的方法相同,例如:
# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}
注释
单行注释
使用# 注释
多行注释:
方法一
: '
被注释的多行内容
'
方法二
:<<eof
被注释的多行内容
eof
方法三
:<<!
被注释的多行内容
!
方法四
if false ; then
被注释的多行内容
fi