shell编程lesson12

        之前一节,我们了解了字符串和整数。到目前为止,我们所接触到的数据类型在计算机科学领域被称为标量变量,也就是说,变量只包含一个单一值。

        本次我们学习一种包含多个值的数据结构——数组。事实上,数组几乎是所有程序设计语言的一大特点。尽管shell对数组的支持有限,但它对于解决程序设计问题是非常有帮助的。

什么是数组

        数组是可以一次存放多个值的变量。数组单元叫做元素,并且每个元素中含有数据。通过使用索引或叫下标就可以访问一个独立的数组元素。

        bash中的数据是一维的。

创建数组

        命名数组变量同命名其他bash变量一样,当访问数组变量时可以自动创建。

a[1]=foo

echo ${a[1]}

创建了数组a

declare -a a

declare命令创建数组a。

数组赋值

赋值的方式有两种。

        1、使用下面的语法结构可以赋单一值。

        name[subscript]=value

这里name是数组名,并且subscript是大于或等于0的整数。需要注意的是数组的第一个元素的subscript是0,而不是1。value是赋给数组元素的字符串或整数。

       2、使用下面的语法结构可以赋多值。

        name=(value1 value2 ...)

这里name是数组名,并且将value1 value2...等值依次赋予从下标0开始的数组元素。

例如,想要将一星期中天数的缩写赋给数组days,那么可以

days=(Sun Mon Tue Wed Thu Fri Sat)

通过为每个值指定一个下标来给特定元素赋值也是可以的

days=([0]=Sun [1]=Mon [2]=Tue [3]=Wed [4]=Thu [5]=Fri [6]=Sat)

访问数组元素

以一个简单的数据采集和表示为例。创建一个脚本,用于校验特定目录中文件的修改次数。

#!/bin/bash

# hours:script to count files by modification time

usage () {
    echo "Usage:$(basename $0) directory" >&2
}

# check that argument is a directory
if [[ ! -d $1 ]];then
    usage
    exit 1
fi

# initialize array
for i in {0..23};do hours[i]=0;done

# collect data
for i in $(stat -c %y "$1"/* | cut -c 12-13);do
    j=${i/#0}
    ((++hours[i]))
    ((++count))
done

# display data
echo -e "Hour\tFiles\tHour\tFiles"
echo -e "----\t----\t----\t----"
for i in {0..11};do
    j=$((i+12))
    printf "%02d\t%d\t%02d\t%d\n" $i ${hours[i]} $j ${hours[j]}
done
printf "\nTotal files = %d\n" $count

数组操作

        有很多常见的数组操作。比如打印出数组、确定数组元素的个数、查找数组元素的下标、在数组的结尾添加元素、数组排序操作、数组的删除(删除整个数组、删除单个数组元素等)。

输出数组的所有内容

我们可以使用下标“*”和“@”来访问数组中的每个元素。

#!/bin/bash
animals=("a dog" "a cat" "a fish")
for i in ${animals[*]};do echo $i;done
echo "-------------------------"
for i in ${animals[@]};do echo $i;done
echo "+++++++++++++++++++++++++"
for i in "${animals[*]}";do echo $i;done
echo "========================="
for i in "${animals[@]}";do echo $i;done

输出结果

a
dog
a
cat
a
fish
-------------------------
a
dog
a
cat
a
fish
+++++++++++++++++++++++++
a dog a cat a fish
=========================
a dog
a cat
a fish

        创建了数组animals,并使用3个双单词字符串作为数组元素,然后执行4个循环,观察单词拆分对数组内容的影响。

        如果对符号${animals[*]}和${animals[@]}加以引用,就会得到不同的结果。符号“*”将数组所有内容放在一个字符串中,而符号“@”使用3个字来显示数组的真是内容。

        "${animals[@]}"更能体现出数组内容的正确性,更加适用。

确定数组元素的个数

        使用参数扩展,我们可以采用类似获取字符串长度的方式来确定数组中元素的个数。

a[100]=foo
echo ${#a[@]} # number of array elements

echo ${#a[100]} # length of element 100

echo ${#a[@]}输出结果为1,表示数组a中的元素个数为1.

echo ${#a[100]}输出结果为3,表示下标为100的数组元素值的长度。

值得一提的是,当将字符串赋给下标100时,bash报告数组中只有一个元素。这与其他一些编程语言的行为是不同的,这些语言中,数组中未使用的下标(0~99)元素初始化为空值并参与数组长度计数。bash数组不同!!!

查找数组中使用的下标

        ${!array[*]}

        ${!array[@]}

这里,array是数组变量名。

foo=([2]=a [4]=b [6]=c)
for i in "${foo[@]}";do echo $i;done
# output:
# a
# b
# c
for i in "${!foo[@]}";do echo $i;done
# output:
# 2
# 4
# 6

在数组的结尾增加元素

        shell通过使用“+=”赋值运算符,可以在数组的尾部自动地添加元素。这里我们将3个值赋给数组foo,然后再添加3个元素。

foo=(a b c)
echo ${foo[@]}
# 输出:a b c
foo+=(d e f)
echo ${foo[@]}
# 输出:a b c d e f

数组排序操作

        shell没有直接的排序功能,但是可以用一些代码来完成。

#!/bin/bash

# array-sort:sort an array

a=(f e d c b a)
echo "Original array:${a[@]}" # 输出结果:Original array:f e d c b a
a_sorted=($(for i in "${a[@]}";do echo $i;done | sort))
echo "Sorted array:${a_sorted[@]}" # 输出结果:Sorted array:a b c d e f

脚本巧妙地使用一个替换命令将原数组a的内容复制到数组a_sorted中。

通过改变设计流程,我们可以将这个技术用来执行数组中的多种操作。

数组的删除

使用unset命令,我们可以删除数组。

foo=(a b c d e f)
echo ${foo[@]} # 输出 a b c d e f
unset foo
echo ${foo[@]} # 输出 空

也可以使用unset删除单个数组元素

foo=(a b c d e f)
echo ${foo[@]} # 输出 a b c d e f

unset 'foo[2]'
echo ${foo[@]} # 输出 a b d e f

对数组foo的第3个元素(下标为2)进行删除。记住!数组是以下标0开始的,而不是1开始的!同时需要注意的是,我们必须引用数组元素来阻止shell执行路径名扩展。

        很有趣的是,对数组变量进行赋空值,并不会清空数组内容。

foo=(a b c d e f)
foo=
echo ${foo[@]} # 输出 b c d e f

         任何涉及到不含下标的数组变量的引用指的是数组中的元素0,如下所示

foo=(a b c d e f)
echo ${foo[@]} # 输出 a b c d e f
foo=A
echo ${foo[@]} # 输出 A b c d e f

数组和循环经常结合使用,来解决多种程序设计问题。

Shell编程是指在Unix/Linux操作系统下,使用命令行界面或脚本语言编写一系列命令来完成特定任务的编程方式。其主要用途包括:

1. 系统管理:可以编写Shell脚本来自动化执行各种系统管理任务,如备份文件、安装软件、监控系统状态等。

2. 批处理:可以编写Shell脚本来批量处理文件、数据和日志等任务,提高效率和减少人工错误。

3. Web开发:可以使用Shell编写Shell脚本来自动化构建、测试和部署Web应用程序。

4. 数据处理:可以使用Shell编写Shell脚本来处理各种类型的数据,例如文本、XML、JSON和CSV等。

5. 安全审计:可以使用Shell编写Shell脚本来查找和修复系统安全漏洞,提高系统安全性。

总之,Shell编程可以帮助我们快速、高效地完成各种系统管理和数据处理任务,提高工作效率和准确性。

你可能感兴趣的:(linux,数学建模,bash,服务器,运维,linux)