在Bash中遍历字符串数组的方法

在Bash中遍历字符串数组的方法

技术背景

在Bash脚本编程中,经常需要对数组进行操作,其中遍历数组是一个常见的需求。通过遍历数组,可以对数组中的每个元素执行相同或不同的操作,从而实现自动化处理和批量操作。

实现步骤

1. 声明数组

可以使用多种方式声明数组,以下是几种常见的方式:

1
2
3
4
5
6
7
8
9
10
11
# 方式一
declare -a arr=("element1" "element2" "element3")

# 方式二
arr=("element1" "element2" "element3")

# 方式三,多行声明
declare -a arr=("element1"
"element2" "element3"
"element4"
)

2. 遍历数组

以下是几种不同的遍历数组的方法:

基本的for循环遍历

1
2
3
4
5
declare -a arr=("element1" "element2" "element3")
for i in "${arr[@]}"
do
echo "$i"
done

使用计数器遍历

1
2
3
4
5
6
declare -a array=("one" "two" "three")
arraylength=${#array[@]}
for (( i=0; i<${arraylength}; i++ ));
do
echo "index: $i, value: ${array[$i]}"
done

遍历列表变量

1
2
3
4
5
List=( Item1 Item2 Item3 )
for Item in ${List[*]}
do
echo $Item
done

遍历关联数组

1
2
3
4
5
6
7
8
declare -A continent
continent[Vietnam]=Asia
continent[France]=Europe
continent[Argentina]=America
for item in "${!continent[@]}";
do
printf "$item is in ${continent[$item]} \n"
done

处理CSV格式的列表

1
2
3
4
5
6
7
8
List="Item 1,Item 2,Item 3"
Backup_of_internal_field_separator=$IFS
IFS=,
for item in $List;
do
echo $item
done
IFS=$Backup_of_internal_field_separator

3. 其他技巧

隐式数组处理脚本或函数参数

1
2
3
4
set -- arg1 arg2 arg3
for item ;do
echo "This is item: $item."
done

使用数组键列表遍历

1
2
3
4
declare -a arr=("element 1" "element 2" "element 3")
for i in "${!arr[@]}";do
printf 'Field id:%2d is "%s".\n' "$i" "${arr[i]}"
done

核心代码

以下是一个完整的示例,展示了多种遍历数组的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#!/bin/bash

# 声明数组
declare -a arr=("element1" "element2" "element3")

# 基本的for循环遍历
echo "基本的for循环遍历:"
for i in "${arr[@]}"
do
echo "$i"
done

# 使用计数器遍历
echo "使用计数器遍历:"
arraylength=${#arr[@]}
for (( i=0; i<${arraylength}; i++ ));
do
echo "index: $i, value: ${arr[$i]}"
done

# 遍历列表变量
echo "遍历列表变量:"
List=( Item1 Item2 Item3 )
for Item in ${List[*]}
do
echo $Item
done

# 遍历关联数组
echo "遍历关联数组:"
declare -A continent
continent[Vietnam]=Asia
continent[France]=Europe
continent[Argentina]=America
for item in "${!continent[@]}";
do
printf "$item is in ${continent[$item]} \n"
done

# 处理CSV格式的列表
echo "处理CSV格式的列表:"
List="Item 1,Item 2,Item 3"
Backup_of_internal_field_separator=$IFS
IFS=,
for item in $List;
do
echo $item
done
IFS=$Backup_of_internal_field_separator

# 隐式数组处理脚本或函数参数
echo "隐式数组处理脚本或函数参数:"
set -- arg1 arg2 arg3
for item ;do
echo "This is item: $item."
done

# 使用数组键列表遍历
echo "使用数组键列表遍历:"
declare -a arr2=("element 1" "element 2" "element 3")
for i in "${!arr2[@]}";do
printf 'Field id:%2d is "%s".\n' "$i" "${arr2[i]}"
done

最佳实践

  • 引号的使用:在遍历数组时,建议使用双引号来引用数组扩展 ${arr[@]},以避免元素中的空格被错误分割。
  • 计数器的使用:如果需要访问数组元素的索引,可以使用计数器的方式进行遍历。
  • 关联数组的使用:当需要使用键值对的形式存储数据时,可以使用关联数组。

常见问题

  • 空格问题:如果数组元素中包含空格,不使用引号会导致元素被错误分割。例如:
1
2
3
4
5
listOfNames="RA RB R C RD"
for databaseName in $listOfNames
do
echo "$databaseName"
done

输出结果会将 R C 分割成两个元素。正确的做法是使用双引号:

1
2
3
4
5
listOfNames="RA RB R C RD"
for databaseName in "$listOfNames"
do
echo "$databaseName"
done
  • 不同Shell的兼容性问题:不同的Shell(如Bash、Korn shell)在数组声明和使用上可能存在差异。为了编写兼容所有Shell的脚本,可以使用以下方式:
1
2
3
4
5
set -A databaseName=("db1" "db2") || declare -a databaseName=("db1" "db2")
for dbname in "${databaseName[@]}"
do
echo "$dbname"
done

在Bash中遍历字符串数组的方法
https://119291.xyz/posts/2025-05-15.loop-through-an-array-of-strings-in-bash/
作者
ww
发布于
2025年5月15日
许可协议