Shell脚本编程—数组、字符串处理

数组

变量:存储单个元素的内存空间

数组:存储多个元素的连续的内存空间

    数组名:整个数组只有一个名字;

    数组索引:编号从0开始;

         [数组名索引]

         #{ARRAY_NAME[INDEX]}

     注意:bash-4及之后的版本,支持自定义索引格式,而不仅仅是0,1,2…数字格式

          此类数组称之为"关联数组"

声明数组:

     declare -a NAME:声明索引数组

     declare -A NAME:声明关联数组

数组中元素的赋值方式:

    (1)一次只赋值一个元素

        ARRAY_NAME[INDEX]=value

    (2)一次赋值全部元素

        ARRAY_NAME=("VAL1" "VAL:2" "VAL3" …)

    (3)只赋值特定元素:

        ARRAY_NAME=([0]="VAL1" [3]="VAL4" …)

        注意:bash支持稀疏格式的属组

    (4)read -a ARRAY_NAME

 

引用数组中的元素:${ARRAY_NAME[INDEX]}

    注意:引用时,只给数组名,表示应用下标为0的元素

     ${ARRAY_NAME[*]}:引用数组中的所有元素

     ${ARRAY_NAME[@]}

[root@CentOS7 ~]# array=(one two three four)
[root@CentOS7 ~]# echo ${array[*]}
one two three four
[root@CentOS7 ~]#

数组的长度(数组中元素的个数):

    ${#ARRAY_NAME[*]}

    ${#ARRAY_NAME[@]}

[root@CentOS7 ~]# array=(one two three four)
[root@CentOS7 ~]# echo ${#array[*]}
4
[root@CentOS7 ~]#

引用数组中的所有元素:

    ${ARRAY_NAME[*]}

    ${ARRAY_NAME[@]}

    数组元素切片:${ARRAY_NAME[@]:offset:number}

        offset:要跳过的元素个数

        number:要取出的元素个数;省略number时,表示取偏移量之后的所有元素

[root@CentOS7 ~]# array=(one two three four)
[root@CentOS7 ~]# echo ${array[*]:2}
three four
[root@CentOS7 ~]#

向非稀疏格式数组中追加元素:

    ARRAY_NAME[$[#ARRAY_NAME[*]}]=

删除数组中的某元素:

    unset ARRAY_NAME[INDEX]

关联数组:

    declare -A ARRAY_NAME

    ARRAY_NAME=([index_name1]="value" [index_name2]="value2" …)

示例:

1.生成10个随机数,并找出其中的最大值和最小值

[root@CentOS7 scripts]# cat random.sh 
#!/bin/bash
#

declare -a array
declare -i MAX=0
declare -i MIN=0

for I in $(seq 0 9)
do
	array[$I]=$RANDOM
	[ $I -eq 9 ] && echo "${array[$I]}" || echo -n "${array[$I]} "
	[ $I -eq 0 ] && MIN=${array[$I]}
	[ ${array[$I]} -gt $MAX ] && MAX=${array[$I]}
	[ ${array[$I]} -lt $MIN ] && MIN=${array[$I]}
done

echo "Max is: $MAX"
echo "Min is: $MIN"


[root@CentOS7 scripts]# bash random.sh 
17015 5923 5983 31353 19248 29430 5642 31040 5929 11513
Max is: 31353
Min is: 5642
[root@CentOS7 scripts]#

2.定义一个数组,数组中的元素是/var/log目录下所有以.log结尾的文件;统计其下标为偶数的文件中的行数之和

[root@CentOS7 scripts]# cat sum.sh 
#!/bin/bash
#

declare -a array
declare -i LINESUM=0
array=(/var/log/*.log)

for I in $(seq 0 $[${#array[*]}-1])
do
	if [ $[$I%2] -eq 0 ];then
		LINES=$(wc -l ${array[$I]} | cut -d' ' -f1)
		LINESUM+=$LINES
	fi
done

echo "Lines sum is: $LINESUM"
		
[root@CentOS7 scripts]# bash sum.sh 
Lines sum is: 682
[root@CentOS7 scripts]#

3.输入若干个数值存入数组中,采用冒泡算法进行升序或降序排序

[root@CentOS7 scripts]# cat maopao.sh 
#!/bin/bash
#

echo "Please input a number list"
read -a LIST
echo

for ((I=0;I<${#LIST[*]}-1;I++))
do
	for ((J=0;J<${#LIST[*]}-1;J++))
	do
		if [ ${LIST[$J]} -gt ${LIST[$J+1]} ];then
			TMP=${LIST[$J]}
			LIST[$J]=${LIST[$J+1]}
			LIST[$J+1]=$TMP
		fi
	done
done

echo "after sort"
echo ${LIST[*]}

echo "==============================="

for ((I=0;I<${#LIST[*]}-1;I++))
do
	for ((J=0;J<${#LIST[*]}-1;J++))
	do
		if [ ${LIST[$J]} -lt ${LIST[$J+1]} ];then
			TMP=${LIST[$J]}
			LIST[$J]=${LIST[$J+1]}
			LIST[$J+1]=$TMP
		fi
	done
done

echo "before sort"
echo ${LIST[*]}
[root@CentOS7 scripts]# bash maopao.sh 
Please input a number list
5 10 8 18 3 20

after sort
3 5 8 10 18 20
===============================
before sort
20 18 10 8 5 3
[root@CentOS7 scripts]#

 

 

 

bash字符串处理工具

 

字符串切片

取字符串长度个数

    ${#VAR}:取变量的字符个数

[root@CentOS7 ~]# var=zhai
[root@CentOS7 ~]# echo ${#var}
4
[root@CentOS7 ~]#

字符串你切片:

    ${var:offset:number}:返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,到最后的部分,offset的取值在0 到${#var}-1 之间(bash4.2后,允许为负值)

[root@CentOS7 ~]# echo $test
abcdefghijklmnopqrstuvwxyz
[root@CentOS7 ~]# echo ${test:10}
klmnopqrstuvwxyz
[root@CentOS7 ~]#

    ${var:offset:number}:返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,长度为number的部分

[root@CentOS7 ~]# echo $test
abcdefghijklmnopqrstuvwxyz
[root@CentOS7 ~]# echo ${test:10:10}
klmnopqrst
[root@CentOS7 ~]#

    ${var: -lengh}:取字符串的最右侧几个字符

[root@CentOS7 ~]# echo $test
abcdefghijklmnopqrstuvwxyz
[root@CentOS7 ~]# echo ${test: -10}    #注意冒号之后必须有一个空格
qrstuvwxyz
[root@CentOS7 ~]#

    ${var:offset:-lengh}:从最左侧跳过offset字符,一直取到字符串的最右侧lengh个字符之前

[root@CentOS7 ~]# echo $test
abcdefghijklmnopqrstuvwxyz
[root@CentOS7 ~]# echo ${test:10: -10}
klmnop
[root@CentOS7 ~]#

 

 

基于模式取子串

    ${var#*word}:其中word是指定的分隔符;功能:自左而又,查找var变量所存储的字符串中,第一次出现的word分隔符,删除字符开头至此分隔符之间的所有内容

[root@CentOS7 ~]# echo $test
root:x:0:0:root:/root:/bin/bash
[root@CentOS7 ~]# echo ${test#*:}    #自左而右,以:为分隔符,删除第一次匹配到:之前的所有内容
x:0:0:root:/root:/bin/bash
[root@CentOS7 ~]#

    ${var##*word}:其中word是指定的分隔符;功能:自左而又,查找var变量所存储的字符串中,最后一次出现的word分隔符,删除字符开头至此分隔符之间的所有内容

[root@CentOS7 ~]# echo $test
root:x:0:0:root:/root:/bin/bash
[root@CentOS7 ~]# echo ${test##*:}    #自左而右,最后一次匹配到:之前的所有内容
/bin/bash
[root@CentOS7 ~]#

    ${var%word*}:其中word是指定的分隔符;功能自右而左,查找var变量所存储的字符串中,第一次出现的word分隔符,删除此分隔符至字符串尾部之间的所有字符

[root@CentOS7 ~]# echo $test
root:x:0:0:root:/root:/bin/bash
[root@CentOS7 ~]# echo ${test%:*}    #自右而左,删除第一次匹配到:之后的所有内容
root:x:0:0:root:/root
[root@CentOS7 ~]#

    ${var%%word*}:其中word是指定的分隔符;功能自右而左,查找var变量所存储的字符串中,最后一次出现的word分隔符,删除此分隔符至字符串尾部之间的所有字符

[root@CentOS7 ~]# echo $test
root:x:0:0:root:/root:/bin/bash
[root@CentOS7 ~]# echo ${test%%:*}    #自右而左,删除最后一次匹配到:之后的所有内容
root
[root@CentOS7 ~]#

 

 

查找替换

    ${var/PATTERN/SUBSTI}:查找var所表示的字符串中,第一次被PATTERN所匹配到的字符串,将其替换为SUBSTI所表示的字符串

[root@CentOS7 ~]# echo $test
root:x:0:0:root:/root:/bin/bash
[root@CentOS7 ~]# echo ${test/root/zhai}    #第一次匹配到root的字符替换为zhai
zhai:x:0:0:root:/root:/bin/bash
[root@CentOS7 ~]#

    ${var//PATTERN/SUBSTI}:查找var所表示的字符串中,所有被PATTERN所匹配到的字符串,并将其替换为SUBSTI所表示的字符串

[root@CentOS7 ~]# echo $test
root:x:0:0:root:/root:/bin/bash
[root@CentOS7 ~]# echo ${test//root/zhai}    #替换所有root字符为zhai
zhai:x:0:0:zhai:/zhai:/bin/bash
[root@CentOS7 ~]#

   ${var/#PATTERN/SUBSTI}:查找var所表示的字符串中,行首被PATTERN所匹配到的字符串,将其替换为SUBSTI所表示的字符串 

[root@CentOS7 ~]# echo $test
root:x:0:0:root:/root:/bin/bash
[root@CentOS7 ~]# echo ${test/#root/zhai}    #替换行首为root的字符为zhai
zhai:x:0:0:root:/root:/bin/bash
[root@CentOS7 ~]#

    ${var/%PATTERN/SUBSTI}:查找var所表示的字符串中,行尾被PATTERN所匹配到的字符串,将其替换为SUBSTI所表示的字符串

[root@CentOS7 ~]# echo $test
root:x:0:0:root:/root:/bin/bash
[root@CentOS7 ~]# echo ${test/%bash/nologin}    #替换行尾为bash的字符串为nologin
root:x:0:0:root:/root:/bin/nologin
[root@CentOS7 ~]#

    

 

查找删除

    ${var/PATTERN}:以PATTERN为模式查找var字符串中第一次匹配,并删除之;

[root@CentOS7 ~]# echo $test
root:x:0:0:root:/root:/bin/bash
[root@CentOS7 ~]# echo ${test/root}    #删除第一次出现root的字符
:x:0:0:root:/root:/bin/bash
[root@CentOS7 ~]#

    ${var//PATTERN}:以PATTERN为模式查找var字符串中所有匹配,并删除之;

[root@CentOS7 ~]# echo $test
root:x:0:0:root:/root:/bin/bash
[root@CentOS7 ~]# echo ${test//root}    #删除所有root字符串
:x:0:0::/:/bin/bash
[root@CentOS7 ~]#

    ${var/#PATTERN}:以PATTERN为行首查找var字符串中的匹配到的字符串,并删除

[root@CentOS7 ~]# echo $test
root:x:0:0:root:/root:/bin/bash
[root@CentOS7 ~]# echo ${test/#root}    #删除root开头的字符串
:x:0:0:root:/root:/bin/bash
[root@CentOS7 ~]#

    ${var/%PATTERN}:以PATTERN为行尾查找var字符串中的匹配到的字符串,并删除

[root@CentOS7 ~]# echo $test
root:x:0:0:root:/root:/bin/bash
[root@CentOS7 ~]# echo ${test/%bash}    #删除以bash结尾的字符串
root:x:0:0:root:/root:/bin/
[root@CentOS7 ~]#

 

 

字符大小写转换

    ${var^^}:把var中的所有字符转换为大小

[root@CentOS7 ~]# echo $test
abcdefghijklmnopqrstuvwxyz
[root@CentOS7 ~]# echo ${test^^}
ABCDEFGHIJKLMNOPQRSTUVWXYZ
[root@CentOS7 ~]#

    ${var,,}:把var中的所有字符转换为小写

[root@CentOS7 ~]# echo $test
ABCDEFGHIJKLMNOPQRSTUVWXYZ
[root@CentOS7 ~]# echo ${test,,}
abcdefghijklmnopqrstuvwxyz
[root@CentOS7 ~]#

 

 

变量赋值

    ${var:-VALUE}:如果var变量为空,或未设置,则返回VALUE,否则输出var变量的值

[root@CentOS7 ~]# echo $test

[root@CentOS7 ~]# echo ${test:-none}    #test变量为空,返回none
none
[root@CentOS7 ~]# test=zhai
[root@CentOS7 ~]# echo ${test:-none}    #test变量不空,返回test变量值
zhai
[root@CentOS7 ~]#

    ${var:=VALUE}:如果var变量为空,或未设置,则返回VALUE,并将VALUE赋值给var变量

[root@CentOS7 ~]# echo $test

[root@CentOS7 ~]# echo ${test:=none}    #test变量值为空,返回none,并把none赋值为变量test
none
[root@CentOS7 ~]# echo $test    #变量test值为none
none
[root@CentOS7 ~]# echo ${test:=true}    #变量test不空,则返回值
none
[root@CentOS7 ~]#

    ${var:+VALUE}:如果var变量不空,则返回VALUE;

[root@CentOS7 ~]# echo $test
zhai
[root@CentOS7 ~]# echo ${test:+true}    #test变量值不空,返回true
true
[root@CentOS7 ~]#

    ${var:?ERROR_INFO}:如果var变量为空,或未设置,则返回ERROR-INFO为错误提示,否则返回var变量的值

[root@CentOS7 ~]# echo $test

[root@CentOS7 ~]# echo ${test:?Error var}    #变量test值为空,返回错误信息
-bash: test: Error var
[root@CentOS7 ~]# echo $?        #命令状态结果为非0
1
[root@CentOS7 ~]# test=zhai
[root@CentOS7 ~]# echo ${test:?Error var}    #变量test值非空,则返回值
zhai
[root@CentOS7 ~]#

 

 

变量类型声明

    Shell变量一般是无类型的,但是bash Shell提供了declare和typeset两个命令用于指定变量的类型

    declare [OPTIONS] VAR

        -r:声明变量为只读变量

        -i:声明变量为整数型变量

        -x:声明变量为环境变量

        -a:声明为索引数组

        -A:声明为关联数组

        -l:声明变量字符为小写

        -u:声明变量字符为大写

        -f:显示此脚本前定义过的所有函数名及其内容

        -F:仅显示此脚本前定义过的所有函数名

 

变量间接引用

    如果第一个变量的值是第二个变量的名字,从第一个变量引用第二个变量的值就称为间接变量引用

    variable1=variable2

    variable2=value

    ariable1的值是variable2,而variable2又是变量名,variable2的值为value,间接变量引用是指通过variable1获得变量值value的行为

    bash提供了两种格式的间接变量引用

    eval tempvar=\$$variable1
    tempvar=${!variable1}

    示例:

[root@CentOS7 ~]# one=two
[root@CentOS7 ~]# two=zhairuixiang
[root@CentOS7 ~]# three=${!one}
[root@CentOS7 ~]# echo $three
zhairuixiang
[root@CentOS7 ~]# eval four=\$$one
[root@CentOS7 ~]# echo $four
zhairuixiang
[root@CentOS7 ~]#

eval命令:将首先扫描命令行进行所有的置换,然后再执行该命令。该命令适用于那些一次扫描无法实现其功能的变量.该命令对变量进行两次扫描

[root@CentOS7 ~]# cmd=whoami
[root@CentOS7 ~]# echo $cmd
whoami
[root@CentOS7 ~]# eval $cmd
root
[root@CentOS7 ~]#

原创文章,作者:zhai796898,如若转载,请注明出处:http://www.178linux.com/42280

(0)
zhai796898zhai796898
上一篇 2016-08-30
下一篇 2016-08-31

相关推荐

  • linux中的vim

    什么是vim:     Linux 在命令行下的文本编辑器,很多个别软件的编辑接口都会主动调用vim,所以在 Linux 的系统中使用文字编辑器来编辑你的Linux参数配置文件,在 Linux 的世界中,绝大部分的配置文件都是以 ASCII 的纯文本形态存在,因此利用简单的文字编辑软件就能够修改设置.所有的Unix L…

    Linux干货 2016-08-11
  • 初识Linux之——Linux是如何诞生的

    初识Linux之——Linux是如何诞生的 对于大多数初次接触Linux的童鞋,可能会非常好奇什么是Linux?它是做什么的?为什么那么多高手都喜欢Linux?Linux是如何产生出来的呢?本文将为大家解答释疑,让大家对Linux有一个清晰的概念。 Linux是什么 简单来说,如Windows7、Windows10、安卓、IOS等,Linux是一个计算机操作…

    Linux干货 2016-10-14
  • 计算机组成及Linux初识

    拼一载春秋,搏一生无悔 1. 计算机简介 2. Linux发行版简介 3. Linux哲学思想简介 4. Linux系统上获取命令帮助 5. Linux「12」个基础命令简介 6. Linux发行版基础目录及功能简介 1.计算机简介 电子计算机(英语:computer),亦称电脑,是一种利用「电子学…

    Linux干货 2016-10-27
  • Linux终端类型

    Linux中各种终端的解释 设备终端   键盘鼠标显示器 物理终端( /dev/console ) )   在Linux 系统中,计算机显示器通常被称为控制台终端(Console)。 虚拟终端(tty :teletypewriters, /dev/tty# # 为[1-6])   tty 可有n 个,Ctrl+Alt+…

    Linux干货 2016-10-13
  • read,locate ,find 的总结及相关联系

    read 变量名 read 变量名1 [变量名2] < 文件名不支持管道read 变量名1 [变量名2] <<< “值1 [值2] …”使用read来把输入值分配给一个或者多个shell变量     -p 指定要显示的提示     # read -p…

    Linux干货 2017-08-12
  • N26-第四周作业

    一、复制/etc/skel目录为/home/tuser1,要求/home/tuser1及其内部文件的属组和其它用户均没有任何访问权限。 思路:先用递归操作复制文件,再用chmod改变文件及其下目录权限。 方法一: [root@promote ~]# cp -r /etc/skel /home/tuser1 #复制文件并改名 [root@promote ~]#…

    2017-05-07