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







All Articles