Shell脚本系列(二)
目录
-
Shell脚本系列(一)
-
Shell脚本系列(二)
-
Shell脚本系列(三)
-
Shell脚本系列(四)
-
Shell脚本系列(五)
-
Shell脚本系列(六)
-
Shell脚本系列(七)
-
Shell脚本系列(八)
1、Shell字符串
1.1、字符串定义
字符串的定义可以使用单引号,也可以使用双引号。
单引号的限制是:
1)单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
2)单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。
双引号的优点:
1)双引号里可以有变量
2)双引号里可以出现转义字符
# 单引号定义 str='this is a string' # 双引号定义 # 输出Hello, I know you are "runoob"! your_name='runoob' str="Hello, I know you are \"$your_name\"! \n" echo -e $str
1.2、字符串拼接
your_name="runoob" # 使用双引号拼接 greeting="hello, "$your_name" !" greeting_1="hello, ${your_name} !" echo $greeting $greeting_1 # 使用单引号拼接 greeting_2='hello, '$your_name' !' greeting_3='hello, ${your_name} !' echo $greeting_2 $greeting_3 # 输出 hello, runoob ! hello, runoob ! hello, runoob ! hello, ${your_name} !
1.3、获取字符串长度
方式一:${#字符串}
string="abcd" echo ${#string} #输出 4
方式二:length
string="hello,everyone my name is xiaoming" expr length "$string" ############################## 使用 expr 命令时,表达式中的运算符左右必须包含空格,如果不包含空格,将会输出表达式本身: expr 5+6 // 直接输出 5+6 expr 5 + 6 // 输出 11 对于某些运算符,还需要我们使用符号"\"进行转义,否则就会提示语法错误。 expr 5 * 6 // 输出错误 expr 5 \* 6 // 输出30
1.4、提取子字符串
# 以下实例从字符串第 2 个字符开始截取 4 个字符: # 第一个字符的索引值为 0。
string="runoob is a great site" echo ${string:1:4} # 输出 unoo
1.5、查找子字符串
注意啊,该命令输出的是位置,而不是索引,所以当其返回为0是,就是没找到。
# 查找字符 i 或 o 的位置(哪个字母先出现就计算哪个): # 以下脚本中 ` 是反引号,而不是单引号 ',不要看错了哦。 string="runoob is a great site" echo `expr index "$string" io` # 输出 4
1.6、字符串截取扩展
假设有变量var=http://www.aaa.com/123.htm
1.6.1、# 号截取,删除左边字符,保留右边字符
#其中 var 是变量名,# 号是运算符,*// 表示从左边开始删除第一个 // 号及左边的所有字符 即删除 http://。结果是 :www.aaa.com/123.htm echo ${var#*//}
1.6.2、## 号截取,删除左边字符,保留右边字符
##*/ 表示从左边开始删除最后(最右边)一个 / 号及左边的所有字符 即删除 http://www.aaa.com/。结果是 123.htm echo ${var##*/}
1.6.3、%号截取,删除右边字符,保留左边字符
%/* 表示从右边开始,删除第一个 / 号及右边的字符,结果是:http://www.aaa.com echo ${var%/*}
1.6.4、%% 号截取,删除右边字符,保留左边字符
%%/* 表示从右边开始,删除最后(最左边)一个 / 号及右边的字符。结果是:http: echo ${var%%/*}
1.6.5、从左边第几个字符开始,及字符的个数
其中的 0 表示左边第一个字符开始,5 表示字符的总个数。结果是:http: echo ${var:0:5}
1.6.6、从左边第几个字符开始,一直到结束
其中的 7 表示左边第8个字符开始,一直到结束。结果是 :www.aaa.com/123.htm echo ${var:7}
1.6.7、从右边第几个字符开始,及字符的个数
其中的 0-7 表示右边算起第七个字符开始,3 表示字符的个数。结果是:123 echo ${var:0-7:3}
1.6.8、从右边第几个字符开始,一直到结束
表示从右边第七个字符开始,一直到结束。结果是:123.htm 注:(左边的第一个字符是用 0 表示,右边的第一个字符用 0-1 表示) echo ${var:0-7}
总结:
#、## 表示从左边开始删除。一个 # 表示从左边删除到第一个指定的字符;两个 # 表示从左边删除到最后一个指定的字符。
%、%% 表示从右边开始删除。一个 % 表示从右边删除到第一个指定的字符;两个 % 表示从左边删除到最后一个指定的字符。
删除包括了指定的字符本身。
2、Shell数组
bash支持一维数组(不支持多维数组),并且没有限定数组的大小。
2.1、数组定义
注意:数组的定义,元素与元素之间是空格,没有逗号。
形式一:
数组名=(值1 值2 ... 值n) 如: array_name=(value0 value1 value2 value3) student_name=("张三" "李四" "王五")
单独给数组元素赋值:
student_name[3]="赵六"
student_name[5]="王八1111"
形式二:
array_name=( value0 value1 value2 value3 ) 如 season=( "spring" "summer" "autumn" "winter" )
2.2、数组元素获取、遍历
1)获取单个元素:${数组名[下标]}
2)获取所有元素:${数组名[@]}
echo "${season[0]}" echo "${season[2]}" echo "season的所有元素是:${season[@]}" echo "student_name的所有元素是:${student_name[@]}"
3)for循环遍历数组
#!/bin/bash arr=(1 2 3 4 5 6 7 8 9 10) for a in ${arr[*]} do echo $a done
2.3、获取数组长度
方式一:${#数组名[@]}
方式二:${#数组名[*]}
echo "season数组的长度是:${#season[@]}" echo "season数组的长度是:${#season[*]}" echo "student_name数组的长度是:${#student_name[@]}" echo "student_name数组的长度是:${#student_name[*]}" echo "season数组第三个元素是${season[2]},长度是:${#season[2]}" echo "student_name数组第五个元素是${student_name[5]},长度是:${#student_name[5]}"
3、Shell传参
我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……。但是需要注意的是$0 为执行的文件名(包含文件路径)。
echo "Shell 传递参数实例!"; echo "执行的文件名:$0"; echo "第一个参数为:$1"; echo "第二个参数为:$2"; echo "第三个参数为:$3"; 为脚本设置可执行权限,并执行脚本,输出结果如下所示: $ chmod +x test.sh $ ./test.sh 1 2 3 Shell 传递参数实例! 执行的文件名:./test.sh 第一个参数为:1 第二个参数为:2 第三个参数为:3
除了$0,$1,$2外,还有几个特殊的参数:
1)$# —— 传递到脚本的参数个数
2)$* —— 以一个单字符串显示所有向脚本传递的参数。$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。
3)$$ —— 脚本运行的当前进程ID号
4)$! —— 后台运行的最后一个进程的ID号
5)$@ —— 与$*相同,但是使用时加引号,并在引号中返回每个参数。$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。
6)$- —— 显示Shell使用的当前选项,与set命令功能相同。
7)$? —— 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
$* 与 $@ 区别:
1)相同点:都是引用所有参数。
2)不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 " * " 等价于 "1 2 3"(传递了一个参数),而 "@" 等价于 "1" "2" "3"(传递了三个参数)。
4、其他
4.1、字符串截取附例
#!/bin/bash # 字符串截取(界定字符本身也会被删除) str="www.runoob.com/linux/linux-shell-variable.html" echo "str : ${str}" echo "str#*/ : ${str#*/}" # 从 字符串开头 删除到 左数第一个'/' echo "str##*/ : ${str##*/}" # 从 字符串开头 删除到 左数最后一个'/' echo "str%/* : ${str%/*}" # 从 字符串末尾 删除到 右数第一个'/' echo "str%%/* : ${str%%/*}" # 从 字符串末尾 删除到 右数最后一个'/' echo echo "str#/* : ${str#/*}" # 无效果 echo "str##/* : ${str##/*}" # 无效果 echo "str%*/ : ${str%*/}" # 无效果 echo "str%%*/ : ${str%%*/}" # 无效果 输出结果: str : www.runoob.com/linux/linux-shell-variable.html str#*/ : linux/linux-shell-variable.html str##*/ : linux-shell-variable.html str%/* : www.runoob.com/linux str%%/* : www.runoob.com str#/* : www.runoob.com/linux/linux-shell-variable.html str##/* : www.runoob.com/linux/linux-shell-variable.html str%*/ : www.runoob.com/linux/linux-shell-variable.html str%%*/ : www.runoob.com/linux/linux-shell-variable.html
4.2、数组遍历附例
#!/bin/bash my_arry=(a b "c","d" abc) echo "-------FOR循环遍历输出数组--------" for i in ${my_arry[@]}; do echo $i done echo "-------::::WHILE循环输出 使用 let i++ 自增:::::---------" j=0 while [ $j -lt ${#my_arry[@]} ] do echo ${my_arry[$j]} let j++ done echo "--------:::WHILE循环输出 使用 let "n++ "自增: 多了双引号,其实不用也可以:::---------" n=0 while [ $n -lt ${#my_arry[@]} ] do echo ${my_arry[$n]} let "n++" done echo "---------::::WHILE循环输出 使用 let m+=1 自增,这种写法其他编程中也常用::::----------" m=0 while [ $m -lt ${#my_arry[@]} ] do echo ${my_arry[$m]} let m+=1 done echo "-------::WHILE循环输出 使用 a=$[$a+1] 自增,个人觉得这种写法比较麻烦::::----------" a=0 while [ $a -lt ${#my_arry[@]} ] do echo ${my_arry[$a]} a=$[$a+1] done
参考:https://www.runoob.com/linux/linux-shell.html