如何在bash中移动数组值


8

我们要构建6个挂载点文件夹作为示例

/data/sdb
/data/sdc
/data/sdd
/data/sde
/data/sdf
/data/sdg

所以我们使用数组编写了这个简单的bash脚本

folder_mount_point_list="sdb sdc sdd sde sdf sdg"

folderArray=( $folder_mount_point_list )

counter=0
for i in disk1 disk2 disk3 disk4 disk4 disk5 disk6
do
folder_name=${folderArray[counter]}
mkdir /data/$folder_name
let counter=$counter+1
done

现在我们要更改不带计数器的代码,并让= $ counter = counter + 1

是否有可能转移每个循环数组以获得下一个数组值?

${folderArray[++]}

1
这是什么意思for i in disk1 disk2 disk3 disk4 disk4 disk5 disk6,因为它没有在循环体内使用?
RomanPerekhrest

1
...使用计数器有什么意义?你为什么不干脆跑for i in "your_list_goes_here"; do mkdir /data/"$i"; done
don_crissti

Answers:


10

一个一般性的评论。定义这样的数组是没有意义的:

folder_mount_point_list="sdb sdc sdd sde sdf sdg"
folderArray=( $folder_mount_point_list )

您可以改为:

folderArray=(sdb sdc sdd sde sdf sdg)

现在您的问题:

set -- sdb sdc sdd sde sdf sdg
for folder_name; do
    mkdir "/data/$folder_name"
done

要么

set -- sdb sdc sdd sde sdf sdg
while [ $# -gt 0 ]; do
    mkdir "/data/$1"
    shift
done

我们可以将变量设置为集合吗-$ list_of_folders(而list_of_folders =“ sdb sdc sdd sde”
yael

@yael是的,您可以使用set -- $list_of_folders但可以再次使用:不能使用字符串变量:set -- "${folders[@]}"
Hauke Laging

1
你为什么还要用set -- ....?hack仅在不支持数组的shell中需要-在支持数组的shell中不需要。 for folder_name in "${folderArray[@]}"; do ... ; done就是所需要的。
cas

只是一个问题,是否有其他选择可以做-$ {folderArray [++]}
yael

@cas就是我的答案。我也没有这种set方法。
PesaThe

14

要回答标题中的问题,您可以使用substring / subarray表示法“移动”一个数组。(shift本身仅与位置参数一起使用。)

$ a=(a b c d e)
$ a=("${a[@]:1}")
$ echo "${a[@]}"
b c d e

类似地,要“弹出”数组中的最后一项:a=("${a[@]:0:${#a[@]} - 1}" )unset "a[${#a[@]}-1]"

因此,如果您愿意,可以这样做:

a=(foo bar doo)
b=(123 456 789)
while [ "${#a[@]}" -gt 0 ] ; do
    echo "$a $b"
    a=("${a[@]:1}")
    b=("${b[@]:1}")
done

但这会浪费数组,因此仅照常进行索引可能会更好。或者也许使用关联数组:

declare -A arr=([foo]=123 [bar]=456 [doo]=789)

4

您可以简单地遍历所有值,而无需移动:

folderArray=(sdb sdc sdd sde sdf sdg)

for folder in "${folderArray[@]}"; do
    mkdir "/data/$folder"
done

3

您不需要任何循环:

folderArray=(sdb sdc sdd sde sdf sdg)
IFS=,
eval mkdir /data/{"${folderArray[*]}"}

诀窍是,如果数组用下标*"${array[*]}")双引号,它将扩展为一个单词,每个数组元素的值都由IFS变量的第一个字符分隔。之后,我们使用括号扩展机制将其附加/data/到每个数组成员,eval并对整个对象进行初始化。


为什么这么复杂?cd /data ; mkdir "${folderArray[@]}"我之前也做过同样的事情,但在这种情况下我不会。但是+1是高级方法。
Hauke Laging,

@HaukeLaging是的,如果使用mkdir命令,那会更简单。甚至不需要数组,就像cd /data; mkdir abc def普通人那样。但是对于其他任务来说可能不那么简单,因此最好知道如何快速将字符串附加到每个数组元素而无需循环。
jimmij

只是一个问题,是否有其他选择可以做-$ {folderArray [++]}
yael

1
@yael echo "${folderArray[((counter++))]}"如果您真的喜欢这种方法,则可以执行类似操作。内部的内容(())被评估为数学运算(注意$前面没有counter)。
jimmij

1
当您开始编写这样的shell代码时,您意识到花一点时间来学习perl或python是一个好主意。即仅仅因为您可以用bash做某事,并不意味着您应该这样做
cas
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.