在bash中循环动态生成的数组

时间:2016-05-24 07:16:12

标签: arrays bash loops

我正在尝试编写一个执行具有不同扩展名的文件操作的脚本。为了便于添加不同的操作,可以从数组中读取扩展名,通过" find"命令和结果返回到以搜索的文件扩展名命名的动态生成的数组。

要添加新扩展名以进行搜索,我只需添加到file_ext数组即可。

我像这样创建数组:

file_exts=("dsd" "dsdd" "dmesg")

for ext in "${file_exts[@]}"
do

        echo "Finding $ext files"
        eval var="exts_$ext"

        declare -a $var="($( find "$dirs_target" -name "*.$ext"))"

done

正确创建数组,我可以手动回显" $ {exts_dsd [0]} $ {exts_dsd [1]}"并查看条目,但是,我找不到循环遍历动态分配的数组中每个条目的方法。

我已经尝试了一些使用eval的组合,我可以打印出数组中的第一个条目,IE只是引用" $ exts_dsd"以下是我已尝试过的两件事:

for varname in "${!exts_@}"
do

        for entry in ${varname[@]}
        do
                echo "$varname : $entry"
        done

        eval value=\$${varname[@]}       

        echo "$varname=$value"
done

如何遍历上面的for循环中的每个条目,这样我就可以打印出所有动态创建的数组中的所有条目?

这是一个完整的测试脚本:

#! /bin/bash


file_exts=("dsd" "dsdd" "dmesg")
dirs_target="/tmp/arraytest/"

echo "Creating $dirs_target"
if [[ ! -d "$dirs_target" ]]; then

        if ! mkdir "$dirs_target"; then
                echo "Couldn't create temp dir"
                exit 1
        fi
fi

echo "Creating test files"
for tmpfile in $( seq 0 5 )
do
        echo -e "\tCreating $dirs_target$tmpfile.dsd"
        if ! touch "$dirs_target/$tmpfile.dsd"; then
                echo "Coudn't create $dirs_target/test$tmpfile.dsd"
                exit 1
        fi
done

echo ""
echo "-----Finding Files-----"
for ext in "${file_exts[@]}"
do

        echo "Finding $ext files"
        eval var="exts_$ext"

        declare -a $var="($( find "$dirs_target" -name "*.$ext"))"

done
echo ""
echo "-----File Extensions-----"
for varname in "${!exts_@}"
do

        for entry in ${varname[@]}
        do
                echo "$varname : $entry"
        done
        eval value=\$${varname[@]}
        #echo "$varname=$value"
done

echo ""
echo "Finishing."
rm -rf "$dirs_target"

2 个答案:

答案 0 :(得分:2)

要遍历条目,您必须使用与创建条目时相同的技巧:只需将变量名称存储在变量中。关键是要包含[@]索引,它将在间接中正确识别:

for varname in "${!exts_@}" ; do
    arr=$varname'[@]'
    for entry in "${!arr}" ; do
        echo "$varname : $entry"
    done
done

另请注意

中不需要eval
# eval var="exts_$ext"
var=exts_$ext  # works even better!

答案 1 :(得分:0)

我找到了答案。我的eval声明有点不对。

echo "-----File Extensions-----"
for varname in "${!exts_@}"
do

        echo "varname=$varname"

        eval testvalue="\${$varname[@]}"

        for entry in $testvalue
        do
                echo -e "\tFile: $entry"
        done

done

作为奖励,我还想出了如何添加到动态创建的数组

 var="table_$entry"
 declare -a $var   

 while read -r line
 do
        eval $var+=\(\'"$line"\'\)

 done < "$dirs_table"