How do I create a set-like array in bash?
Suppose I have the following list of files:
/aaa/bbb/file1.txt /aaa/ccc/file2.txt /aaa/bbb/file3.txt /aaa/bbb/file4.txt /aaa/ccc/file5.txt
And I would like to have a set of all unique dirnames in the array. The resulting array will look something like this:
dirs=( "/aaa/bbb" "/aaa/ccc" )
I think I can do something like this, but it feels really verbose (sorry for syntax errors, I don't have a shell):
dirs=()
for f in filelist do
dir=$(dirname $f)
i=0
while [$i -lt ${#dirs[@]} ]; do
if [ dirs[$i] == $dir ]
break
fi
i=$[i + 1]
done
if [ $i -eq ${dirs[@]} ]
dirs+=($dir)
fi
done
+3
source to share
1 answer
Using associative arrays:
declare -A dirs
for f in "${filelist[@]}"; do
dir=$(exec dirname "$f") ## Or dir=${f%/*}
dirs[$dir]=$dir
done
printf '%s\n' "${dirs[@]}"
Or if the input is from a file:
readarray -t files < filelist
for f in "${files[@]}"; do
dir=$(exec dirname "$f") ## Or dir=${f%/*}
dirs[$dir]=$dir
done
- Don't leave unnecessary forks on the subshell minimum with
exec
.
+2
source to share