天天看点

简单高效的Shell数组操作技巧与技术

作者:小毛驴的烂笔头

Shell Array

数组是Shell脚本中一种常用的数据结构,用于存储一组数据。在Shell中,我们可以使用各种技巧来操作数组,包括数组的取值、移除数组中匹配的字符以及判断一个值是否在数组中。下面是一些常用的Shell数组操作技巧。

数组的初始化

使用空格分隔的元素初始化数组:
# 创建一个名为arrayZ的数组,其中包含了6个元素。
arrayZ=( one two three four five five )           
使用冒号分隔的元素,并使用字符串替换进行数组初始化:
str="a:b:c:d:e"
set -f # 避免通配符扩展(*的扩展)
arr=(${str//:/ }) 
# 现在数组arr包含了值 'a', 'b', 'c', 'd', 'e'           
使用'tr'命令将冒号替换为换行符进行数组初始化
str="a:b:c:d:e"
arr=($(echo $str | tr ':' "\n"))
# 现在数组arr包含了值 'a', 'b', 'c', 'd', 'e'           
使用'sed'命令将冒号替换为换行符进行数组初始化:
str="a:b:c:d:e"
arr=($(echo $str | sed 's/:/\n/g'))
# 现在数组arr包含了值 'a', 'b', 'c', 'd', 'e'           
使用'IFS'(内部字段分隔符)和'eval'命令进行数组初始化:
str="a:b:c:d:e"
IFS=':' eval 'arr=($str)'
# 现在数组arr包含了值 'a', 'b', 'c', 'd', 'e'           

数组的访问

比如有如下一个数组: arrayZ=(one two three four five five)

使用${array[@]}或${array[*]}可以获取数组中的所有元素。
# 获取所有元素
echo ${arrayZ[@]}   # 输出: one two three four five five
echo ${arrayZ[*]}   # 输出: one two three four five five           
使用${array[@]:1}可以获取数组中从第二个元素开始的所有元素。
echo ${arrayZ[@]:1} //two three four five            
使用${array[@]:2:3}可以获取数组中从第三个元素开始的三个元素。
# 获取从第三个元素开始的三个元素
echo ${arrayZ[@]:2:3}   # 输出: three four five           
使用${#array[*]}或${#array[@]}可以获取数组中元素的个数。
# 获取数组中元素的个数
echo ${#arrayZ[*]}   # 输出: 6
echo ${#arrayZ[@]}   # 输出: 6           
使用${#array[0]}可以获取数组中第一个元素的长度。
# 获取第一个元素的长度
echo ${#arrayZ[0]}   # 输出: 3           

数组的操作

使用#和##、%和%%操作符来移除数组中匹配的字符
# 最短匹配和最长匹配
echo ${arrayZ[@]#f*r}  # 移除匹配"four"
echo ${arrayZ[@]##t*e} # 最长匹配,移除匹配"three"

echo ${arrayZ[@]%h*e}  # 移除匹配"four"
echo ${arrayZ[@]%%t*e} # 最长匹配,移除匹配"three"           

判断一个值是否在数组中

使用 grep 命令
arrayZ=( one two three four five five )

# 判断值是否在数组中
echo ${arrayZ[@]:0} | grep -o '\bone\b' > /dev/null
if [ $? -eq 0 ]; then
    echo "值在数组中"
else
    echo "值不在数组中"
fi           

上面的示例中,${arrayZ[@]:0} 用于将数组展开为一个字符串,然后使用 grep 命令匹配值,并通过 -o 参数只输出匹配到的值。如果值在数组中,grep 命令会返回 0,否则返回非零值。通过判断 $? 的值,可以确定值是否在数组中。

使用自定义函数
containsElement () {
    local e
    for e in "${@:2}"; do
        [[ "$e" == "$1" ]] && return 0
    done
    return 1
}

# 判断值是否在数组中
arrayZ=( one two three four five five )
containsElement "onxxx" "${arrayZ[@]}"
if [ $? -eq 0 ]; then
    echo "值在数组中"
else
    echo "值不在数组中"
fi           

上面的示例中,containsElement 函数接受两个参数,第一个参数是要判断的值,第二个参数是数组。函数通过遍历数组中的每个元素,比较是否与要判断的值相等,如果相等则返回 0,表示值在数组中;否则返回非零值,表示值不在数组中。