我正在尝试编写一个执行具有不同扩展名的文件操作的脚本。为了便于添加不同的操作,可以从数组中读取扩展名,通过" 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"
答案 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"