Shell字符串,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、数组元素获取、遍历

${数组名[下标]}

${数组名[@]}

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 脚本时,向脚本传递参数,脚本内获取参数的格式为:$nn 代表一个数字,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

 

     


在全栈的道路上,积极向上、成熟稳重、谦虚好学、怀着炽热的心向前方的走得更远。