SHELL-数组

作者dmxsp

8月 3, 2024

1.Shell数组详解

Shell 数组是Shell脚本编程中的一个重要组成部分,它能够帮助我们在处理复杂数据时更加得心应手。接下来我将详细介绍Shell数组的定义、初始化、访问、遍历以及操作等方面的内容。

2.数组的定义与初始化

Shell 数组是Shell脚本编程中的一个重要组成部分,它可以存储多个值,使得数据的管理更加高效。Shell数组分为普通数组和关联数组两种类型。普通数组使用整数作为索引,而关联数组则可以使用字符串作为索引。数组的定义通常使用小括号(),元素之间用空格分隔。例如,定义一个普通数组nums=(1 2 3),或者关联数组declare -A site([“google”]=”www.google.com”)。

3.数组的索引与访问方法

Shell 数组是 Shell 脚本中非常重要的数据结构之一,它允许程序员在一个单独的变量名下存储多个值。Shell 数组可以用作多种用途,如存储配置选项、处理文件列表等。Shell 数组的索引从0开始,这意味着第一个元素的索引是0,第二个元素的索引是1,依此类推

数组的定义与初始化

Shell 数组的定义相对简单直观。可以通过一行代码声明并初始化一个数组,例如:

array=(元素1 元素2 元素3)

这种方式创建了一个包含三个元素的数组 array,元素可以是数字、字符串或者混合类型

数组元素的访问与赋值

要访问数组中的单个元素,可以使用下标进行索引,下标从0开始。例如,要访问第二个元素:

echo ${array}[1]

这将输出数组 array 中的第二个元素。要给数组元素赋值,可以直接使用赋值语句:

array="新元素"[2]

这将把数组 array 的第三个元素修改为 “新元素”

组的遍历

Shell 脚本中遍历数组有多种方法,常用的是使用循环结构。例如,使用 for 循环遍历数组 array:

for elem in "${array[@]}"; do
echo "$elem"
done

这将逐行输出数组 array 中的所有元素

4.普通数组

使用括号直接指定所有元素

array_name=(value1 value2 ... valuen)

逐个指定每个下标的值

array_name=value0[0]
array_name=value1[1]
array_name=value2[2]

使用特定的命令或变量赋值

array_name=( $(command) )

使用declare命令声明关联数组

declare -a array_name 
array_name=("element1" "element2" "element3")

5.关联数组

Shell 还支持关联数组,也称为映射数组,它的索引是以字符串形式存在的。关联数组的定义和访问稍微复杂一些,需要使用 declare 命令来声明

声明关联数组

declare -A associative_array
associative_array[key1]=value1
associative_array[key2]=value2

访问关联数组

echo ${associative_array[key1]} # 输出 value1

数组的遍历

遍历数组是 Shell 脚本编程中的一项基本技能。可以使用 for 循环来遍历数组中的每个元素:

for element in ${array_name[@]}; do
  echo $element
done

通过数组变量直接访问

如果已经声明了数组变量,可以通过${array_name[index]}的形式来访问特定索引的值。例如,如果我们有一个名为my_array的数组,想要访问第三个元素,可以这样做:

echo ${my_array[2]}

数组的操作

数组的操作包括但不限于:

获取数组长度:${#array_name[@]}、${#array_name[*]}
删除数组元素:取消声明整个关联数组 unset -v fruits 取消声明关联数组中的特定元素 unset -v fruits[“banana”]
清空数组:array_name=()
添加数组元素:array_name+=($new_element)
追加数组元素:可以使用+=操作符在数组末尾追加元素,如array+=(new_element)
替换数组元素:可以使用${array_name[@]/old/new}进行元素值的替换。
数组的切片:使用${array_name[@]:start:end}格式截取数组的一部分。
遍历数组元素使用for循环遍历数组元素,如for elem in ${array[*]}。

6.普通数组与关联数组的区别

普通数组

普通数组是一种数据结构,它是由一系列有序元素组成,每个元素都有一个唯一的数字索引。在大多数编程语言中,普通数组是通过数字索引访问元素的。例如,在Shell脚本中,普通数组的索引从0开始,可以通过${array_name[index]}的方式访问特定索引的元素。在PHP中,普通数组也可以存储不同类型的数据,但通常是按顺序排列的,如整数数组或字符串数组。

关联数组

关联数组,又称为映射数组或字典,是一种使用字符串或其他非数字索引来存储和访问元素的数组。在Shell脚本中,关联数组可以通过declare -A array_name来声明,并通过${array_name[‘key’]}的方式访问特定键的元素。在PHP中,关联数组使用字符串键来标识每个数组元素,非常适合存储需要通过特定名称访问的数据,如用户信息、配置设置等。

区别比较

特征 普通数组 关联数组
索引类型 数字索引 字符串索引
访问方式 通过数字索引访问元素 通过字符串键访问元素
声明 无需特别声明 通常需要使用特定的声明(如declare -A)
遍历 通常使用for循环 通常使用for…in循环
存储 元素通常是顺序排列的 元素是无序的,依赖于键的存在
适用场景 存储顺序排列的数据,如数字序列 存储需要通过名称访问的数据,如键值对

应用场景

普通数组通常用于需要按顺序访问或处理的场景,如存储一系列数字、字符串或对象。关联数组则更适合于需要通过特定键来标识和访问的场景,如表示配置设置或用户信息的键值对。

总结

普通数组和关联数组各有其独特的特点和适用场景。在选择使用哪种类型的数组时,应考虑数据结构的需求和预期用途。正确选择数组类型可以提高代码的可读性和执行效率。

7.declare

declare 命令是 Bash shell 中的一个内置命令,用于声明变量和函数,并可以为变量设置属性。它能够让用户在 Shell 脚本中对变量进行更为精细的控制,包括变量的类型、是否只读、是否全局有效等。

declare 命令的基本语法如下:

declare [options] [name[=value]]

其中 options 是命令的选项,name 是变量或函数的名称,value 是变量的值。如果不指定 name,则 declare 会显示所有变量的属性。

常用选项

-a:声明变量为数组。
-A:声明变量为关联数组(在一些版本的 Bash 中可能不被支持)。
-i:声明变量为整数类型。
-l:将变量转换为小写。
-r:声明变量为只读,一旦设定就不能修改。
-x:声明变量为环境变量,使其在子进程中可用。
-p:显示变量的属性和值。
-f:显示函数的定义。
-u:将变量赋值时转为大写。
-n:创建名称引用。

使用示例

声明关联数组

declare -A array
array["key"]="value"
echo ${array["key"]}

声明整数型变量

declare -i num=10 
echo $num # 输出 10

声明数组变量

declare -a arr=("apple" "banana" "cherry")
echo ${arr} # 输出 banana[1]

声明只读变量

declare -r var="Hello"
echo $var # 输出 Hello
var="World" # 这一行会导致错误,因为 var 是只读变量

显示所有声明的变量

declare -p # 显示所有声明的变量

声明并导出环境变量

declare -x PATH="/usr/local/bin:$PATH"

注意事项

declare 命令在不同版本的 Bash 中可能有细微差别,有些选项可能在旧版本中被废弃或未被支持。

使用 declare 命令时要小心,因为它可能会影响到变量的默认行为。例如,声明为整型的变量在赋值时会进行算术评估。

声明为只读的变量无法再次赋值,这在编写脚本时非常有用,可以防止意外修改变量的值。

统计web的服务器IP地址出现的次数

#!/bin/bash

# 读取日志文件
log_file="/var/log/nginx/access.log"

# 创建一个关联数组来存储 IP 地址及其出现次数
declare -A ip_count

while read line; do
    ip=$(echo "$line" | awk '{print $1}')
    # 如果 IP 已经在数组中,增加计数
    if [ -n "${ip_count[$ip]}" ]; then
        ((ip_count[$ip]++))
    else
        # 如果 IP 不在数组中,初始化为 1
        ip_count[$ip]=1
    fi
done < "$log_file"

# 输出 IP 地址及其出现次数
for ip in "${!ip_count[@]}"; do
    echo "IP: $ip, Count: ${ip_count[$ip]}"
done

 

作者 dmxsp

发表回复

您的电子邮箱地址不会被公开。