Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I create a set-like array in bash?

Tags:

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'd like to have a set of all of the unique dirnames in an array. The resulting array would look something like this:

dirs=( "/aaa/bbb" "/aaa/ccc" )

I think I can do something like this, but it feels really verbose (pardon the syntax errors, i don't have a shell handy):

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
like image 775
awm129 Avatar asked Aug 12 '26 07:08

awm129


1 Answers

Use 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 input is from file:

readarray -t files < filelist
for f in "${files[@]}"; do
    dir=$(exec dirname "$f") ## Or dir=${f%/*}
    dirs[$dir]=$dir
done
  • Let's keep unnecessary forks on a subshell minimum with exec.
like image 175
konsolebox Avatar answered Aug 14 '26 16:08

konsolebox



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!