shell中的数组
杂项知识点
参考文献
SHELL在处理一些问题的时候有得天独厚的优势,快捷方便,学会了还可以显摆显摆,当然了,shell的语法有点坑爹,没有系统的学过,只能一点一点的积累。
今天这个是在实现一个刷新数据库数据的脚本的时候碰到的一些知识点,刷新的时候用到了正则匹配、数学运算、比较等等。
arr=(1 2 3 4 5)arr=(燕睿涛 yrt lulu yanruitao)arr=('^[0-9]+$' '^yrt\.(\d+)\.log$')arr=("燕睿涛" \ "yanruitao" \ "today is a good day!")
数组的使用len=${#arr[@]}#返回的是数组元素的个数echo ${arr[0]}#数组中的第一个元素,这个和其他语言的数组类似,下表从0开始echo ${arr[2]}#数组中的第3个元素
实际的例子[yanruitao@boss_runtime sh]$ arr=(> "燕睿涛"> "http:\/\/www\.baidu\.com\/(\d+)\.html"> "yanruitao"> "lulu"> "yrt"> )[yanruitao@boss_runtime sh]$ echo ${#arr[@]}5[yanruitao@boss_runtime sh]$ echo ${arr[1]}http:\/\/www\.baidu\.com\/(\d+)\.html[yanruitao@boss_runtime sh]$ echo ${arr[0]}燕睿涛[yanruitao@boss_runtime sh]$ echo ${arr[5]}[yanruitao@boss_runtime sh]$
#第一种(())if((6 <8)); then echo "yes 燕睿涛"; fi#输出——yes 燕睿涛if(($a>8)); then echo "yes 燕睿涛"; fiif(($a<=$b)); then echo "yes 燕睿涛"; fi#第二种[] [[]]if [ 2 -gt 1 ]; then echo "iforever 燕睿涛"; fiif [[ 'abc' > 'ab' ]]; then echo "iforever 燕睿涛"; fi#iforever 燕睿涛if [[ 2 < 10 ]]; then echo "iforever 燕睿涛"; fi#无输出if [[ 2 -lt 10 ]]; then echo "iforever 燕睿涛"; fi#iforever 燕睿涛
可以看到上面这几种还是有些规律的:
#看看小括号的用法,首先是在for循环里面,相当于还是数学计算[yanruitao@boss_runtime ad]$ for((a=0;a<10;a++))> do> echo $a> done0123456789#对变量进行++,还是相当于数序运算[yanruitao@boss_runtime ad]$ i=1[yanruitao@boss_runtime ad]$ echo $i1[yanruitao@boss_runtime ad]$ let i++[yanruitao@boss_runtime ad]$ echo $i2[yanruitao@boss_runtime ad]$ ((i++))[yanruitao@boss_runtime ad]$ echo $i3#数学运算[yanruitao@boss_runtime ad]$ echo 1+21+2[yanruitao@boss_runtime ad]$ echo $((1+2))3#单括号里面是一个命令组,括号中的命令将会新开一个shell顺序执行,所以这个里面相当于一个封闭的空间,里面的变量什么的不能被剩余代码使用[yanruitao@boss_runtime ad]$ a=1[yanruitao@boss_runtime ad]$ (a=3;echo $a)3[yanruitao@boss_runtime ad]$ echo $a1#括号中and的使用if [[ -n "$ret" && $ret -gt 123 ]]...#[[]]双中括号中只能使用&&,不能使用-aif [ -n "$ret" -a $ret -gt 123 ]...#[]单中括号中只能使用-a,不能使用&&if(($ret)) && (($ret >123 ))...#(())双小括号使用&&
function getId(){local url=$1#local限定了变量url的作用域只在函数里面,不然会污染全局的作用域 ereg="http:\/\/www\.baidu\.com\/\([0-9]\+\)\.html" local ret=$(exPR $url : $ereg) if [[ -n "$ret" && $ret -gt 0 ]]; then#当ret为null时使用[]会报错,-n这里的双引号一定要加上,不然当$ret为null时,一直返回真 echo $ret return 0 fi return 1}[yanruitao@boss_runtime sh]$ echo $?0[yanruitao@boss_runtime sh]$ getId "http://www.baidu.com/123.htl"[yanruitao@boss_runtime sh]$ echo $?1[yanruitao@boss_runtime sh]$ getId "http://www.baidu.com/123.html"123[yanruitao@boss_runtime sh]$ echo $?0
函数的整体形式如上面的例子,这里面注意两点:
echo $?
可以查看返回值。echo
,就像ret=$(getId "http://www.baidu.com.1234.html")
,只有echo
的值会传递给ret
变量。[yanruitao@boss_runtime sh]$ str="燕睿涛 lulu yrt yanruitao"[yanruitao@boss_runtime sh]$ arr=($str)#这一步将字符串转化为了数组[yanruitao@boss_runtime sh]$ echo ${arr[*]}燕睿涛 lulu yrt yanruitao[yanruitao@boss_runtime sh]$ echo ${#arr[@]}4
常用判断标志[ -z STRING ] “STRING” 的长度为零则为真。 [ -n STRING ] or [ STRING ] “STRING” 的长度为非零 non-zero则为真。[ -d FILE ] 如果 FILE 存在且是一个目录则为真。[ -a FILE ] 如果 FILE 存在则为真。
linux后台运行相关& #在一个命令的最后加上这个命令,可以将该命令放到后台执行./update.sh 100 500 &ctrl + z#讲一个正在前台执行的命令放到后台,并且处于暂停状态jobs#查看当前后台运行的命令jobs -l#可以显示所有后台任务的PID[yanruitao@boss_runtime sh]$ jobs -l[1] 9681 Running ./t.sh 100 300 &[2] 9683 Running ./t.sh 100 300 &[3]- 9685 Running ./t.sh 100 300 &[4]+ 9688 Running ./t.sh 100 300 &fg #把后台中的命令调至前台继续运行,如果后台有多个命令可以使用`fg %jobnumber`将选中命令调出[yanruitao@boss_runtime sh]$ jobs -l[2] 10033 Running ./t.sh 100 300 &[3] 10035 Running ./t.sh 100 300 &[4]- 10037 Running ./t.sh 100 300 &[5]+ 10039 Running ./t.sh 100 300 &[yanruitao@boss_runtime sh]$ fg %2./t.sh 100 300 bg #讲一个在后台暂停的命令变成在后台继续执行。同样,如果有多个命令,可以使用bg %jobnumber[yanruitao@boss_runtime sh]$ jobs -l[1]- 11655 Running ./t.sh 100 300 &[2]+ 11662 Running ./t.sh 100 300 &[yanruitao@boss_runtime sh]$ fg %1./t.sh 100 300^Z[1]+ Stopped ./t.sh 100 300[yanruitao@boss_runtime sh]$ jobs -l[1]+ 11655 Stopped ./t.sh 100 300[2]- 11662 Running ./t.sh 100 300 &[yanruitao@boss_runtime sh]$ bg %1[1]+ ./t.sh 100 300 &[yanruitao@boss_runtime sh]$ jobs -l[1]- 11655 Running ./t.sh 100 300 &[2]+ 11662 Running ./t.sh 100 300 &kill#终止进程kill %num#通过jobs查看的job号,进行杀死kill pid #通过进程号杀掉进程ctrl + C #终止当前前台的进程
AWKawk是强大的文本处理工具。
$awk -F ':' 'BEGIN {count=0;print "[start]user count is ", count} {count=count+1;print $1,"=>",$7;} END{print "[end]user count is ", count}' /etc/passwd
-F
参数指定的是分隔符,对每一分行数据按照他所指定的符号进行分割,默认是空格。{}
之间的内容。很常用的一个操作:
dirname="$(dirname $path)"; //获取目标文件所在的目录ls "$dirname" 1>/dev/null 2>&1 || mkdir -p "$dirname";
重命名命令有时有需要将一个很长的命令(拼起来的目录)缩短,这个时候可以使用下面的方法:
shopt -s expand_aliases; //打开expand_aliases设置,可以进行重命名操作alias log_echo='echo $1'; //设置log_echo 为echo $1的别名,就可以像函数一样使用log_echolog_echo 燕睿涛; //输出燕睿涛log_echo='eval echo $1';$log_echo 燕睿涛; //输出燕睿涛
动态显示进度条shell下面安装软件的时候经常会看到那种动态的进度条什么的,感觉很高大上,其实很好实现,用到了tput命令,下面看个例子:
#!/bin/bashfor i in 1 2 3 4 5 6 7 8 9 10do tput sc;#保存当前光标位置 tput dl1; #删除光标所在函数数据,dl后面的数字是删除的行数 echo -n "loading $i/10"; #不换行的输出双引号的内容 tput rc;#光标回到上次sc(save cursor position)保存的位置 sleep 2;done;
看看效果:
微信号: love_skills
越努力,越幸运!越幸运,越努力!
做上CEO不是梦
赢取白富美不是梦
屌丝逆袭不是梦
就是现在!!加油